diff --git a/solution/0001.Two Sum/Solution.cs b/solution/0001.Two Sum/Solution.cs new file mode 100644 index 0000000000000..4d4e111b7b524 --- /dev/null +++ b/solution/0001.Two Sum/Solution.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; + +public class Solution { + public int[] TwoSum(int[] nums, int target) { + var dict = new Dictionary(); + for (var i = 0; i < nums.Length; ++i) + { + int index; + if (dict.TryGetValue(target - nums[i], out index)) + { + return new [] { index, i}; + } + if (!dict.ContainsKey(nums[i])) + { + dict.Add(nums[i], i); + } + } + return null; + } +} \ No newline at end of file diff --git a/solution/0002.Add Two Numbers/Solution.cs b/solution/0002.Add Two Numbers/Solution.cs new file mode 100644 index 0000000000000..25a5f715dfe18 --- /dev/null +++ b/solution/0002.Add Two Numbers/Solution.cs @@ -0,0 +1,26 @@ +public class Solution { + public ListNode AddTwoNumbers(ListNode l1, ListNode l2) { + return AddInternal(l1, l2, false); + } + + private ListNode AddInternal(ListNode l1, ListNode l2, bool plusOne) + { + if (l1 == null && l2 == null) + { + if (plusOne) + { + return new ListNode(1); + } + return null; + } + + var val = (l1 == null ? 0 : l1.val) + (l2 == null ? 0 : l2.val) + (plusOne ? 1 : 0); + plusOne = val >= 10; + val %= 10; + return new ListNode(val) + { + //next = AddInternal(l1?.next, l2?.next, plusOne); + next = AddInternal(l1 == null ? null : l1.next, l2 == null ? null : l2.next, plusOne) + }; + } +} \ No newline at end of file diff --git a/solution/0003.Longest Substring Without Repeating Characters/Solution.cs b/solution/0003.Longest Substring Without Repeating Characters/Solution.cs new file mode 100644 index 0000000000000..3f00d91556fd3 --- /dev/null +++ b/solution/0003.Longest Substring Without Repeating Characters/Solution.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; + +public class Solution { + public int LengthOfLongestSubstring(string s) { + var hashSet = new HashSet(); + var maxLength = 0; + int i = 0, j = 0; + while (i < s.Length) + { + while (hashSet.Contains(s[i])) + { + hashSet.Remove(s[j++]); + } + hashSet.Add(s[i++]); + if (i - j > maxLength) + { + maxLength = i - j; + } + } + return maxLength; + } +} \ No newline at end of file diff --git a/solution/0004.Median of Two Sorted Arrays/Solution.cs b/solution/0004.Median of Two Sorted Arrays/Solution.cs new file mode 100644 index 0000000000000..494e0c85b96c3 --- /dev/null +++ b/solution/0004.Median of Two Sorted Arrays/Solution.cs @@ -0,0 +1,121 @@ +using System; +using System.Linq; + +class Range +{ + public static Range Empty = new Range(new int[0], 0, -1); + + public readonly int[] Numbers; + public readonly int LeftIndex; + public readonly int RightIndex; + + public int Count { get { return RightIndex - LeftIndex + 1; } } + + public int this[int index] + { + get + { + if (index >= Count) + { + throw new IndexOutOfRangeException(); + } + return Numbers[LeftIndex + index]; + } + } + + public Range(int[] numbers) : this(numbers, 0, numbers.Length - 1) + { + } + + public Range(int[] numbers, int leftIndex, int rightIndex) + { + Numbers = numbers; + LeftIndex = leftIndex; + RightIndex = rightIndex; + if (RightIndex < LeftIndex) RightIndex = LeftIndex - 1; + } + + public Range GetSubRange(int lowerBound, int upperBound) + { + if (lowerBound > upperBound) return Empty; + var leftIndex = lowerBound == int.MinValue ? LeftIndex : Search(lowerBound); + var rightIndex = upperBound == int.MaxValue ? RightIndex : Search(upperBound + 1) - 1; + return new Range(Numbers, leftIndex, rightIndex); + } + + private int Search(int target) + { + var l = 0; + var r = Numbers.Length - 1; + while (l < r) + { + var mid = (l + r) / 2; + if (Numbers[mid] < target) + { + l = mid + 1; + } + else + { + r = mid; + } + } + return Numbers[l] >= target ? l : l + 1; + } +} + +public class Solution { + public double FindMedianSortedArrays(int[] nums1, int[] nums2) + { + var totalNumbers = nums1.Length + nums2.Length; + var targetOrder1 = (totalNumbers + 1)/2; + var targetOrder2 = (totalNumbers + 2)/2; + var range1 = new Range(nums1); + var range2 = new Range(nums2); + var number1 = FindMedianSortedArrays(range1, range2, targetOrder1); + var number2 = targetOrder1 == targetOrder2 ? number1 : FindMedianSortedArrays(range1, range2, targetOrder2); + return ((double) number1 + number2)/2; + } + + private int FindMedianSortedArrays(Range range1, Range range2, int targetOrder) + { + if (range1.Count == 0) + { + return range2[targetOrder - 1]; + } + if (range2.Count == 0) + { + return range1[targetOrder - 1]; + } + + var midNumber = range1[(range1.Count - 1)/2]; + var midRanges = new[] { range1.GetSubRange(midNumber, midNumber), range2.GetSubRange(midNumber, midNumber) }; + var leftRanges = new[] + { + new Range(range1.Numbers, range1.LeftIndex, midRanges[0].LeftIndex - 1), + new Range(range2.Numbers, range2.LeftIndex, midRanges[1].LeftIndex - 1) + }; + var rightRanges = new[] + { + new Range(range1.Numbers, midRanges[0].RightIndex + 1, range1.RightIndex), + new Range(range2.Numbers, midRanges[1].RightIndex + 1, range2.RightIndex) + }; + + var leftCount = leftRanges.Sum(r => r.Count); + var midCount = midRanges.Sum(r => r.Count); + var rightCount = rightRanges.Sum(r => r.Count); + + if (leftCount == 0 && rightCount == 0) + { + return midNumber; + } + if (leftCount >= targetOrder) + { + return FindMedianSortedArrays(leftRanges[0], leftRanges[1], targetOrder); + } + if (leftCount + midCount >= targetOrder) + { + return FindMedianSortedArrays(midRanges[0], midRanges[1], targetOrder - leftCount); + } + return FindMedianSortedArrays(rightRanges[0], rightRanges[1], targetOrder - leftCount - midCount); + } +} \ No newline at end of file diff --git a/solution/0005.Longest Palindromic Substring/Solution.cs b/solution/0005.Longest Palindromic Substring/Solution.cs new file mode 100644 index 0000000000000..984dda03e0dae --- /dev/null +++ b/solution/0005.Longest Palindromic Substring/Solution.cs @@ -0,0 +1,31 @@ +public class Solution { + public string LongestPalindrome(string s) { + var f = new bool[s.Length]; + var maxLen = 0; + var index = 0; + for (var p = 0; p <= 1; ++p) + { + for (var l = 1 + p; l <= s.Length; l += 2) + { + for (var i = 0; i <= s.Length - l; ++i) + { + if (l <= 2) + { + f[i] = s[i] == s[i + l - 1]; + } + else + { + f[i] = f[i + 1] && s[i] == s[i + l - 1]; + } + if (f[i] && l > maxLen) + { + maxLen = l; + index = i; + } + } + } + } + + return s.Substring(index, maxLen); + } +} \ No newline at end of file diff --git a/solution/0006.ZigZag Conversion/Solution.cs b/solution/0006.ZigZag Conversion/Solution.cs new file mode 100644 index 0000000000000..43e3ea8ee76ca --- /dev/null +++ b/solution/0006.ZigZag Conversion/Solution.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using System.Linq; + +public class Solution { + public string Convert(string s, int numRows) { + if (numRows == 1) return s; + if (numRows > s.Length) numRows = s.Length; + var rows = new List[numRows]; + var i = 0; + var j = 0; + var down = true; + while (i < s.Length) + { + if (rows[j] == null) + { + rows[j] = new List(); + } + rows[j].Add(s[i]); + j = j + (down ? 1 : -1); + if (j == numRows || j < 0) + { + down = !down; + j = j + (down ? 2 : -2); + } + ++i; + } + return new string(rows.SelectMany(row => row).ToArray()); + } +} \ No newline at end of file diff --git a/solution/0007.Reverse Integer/Solution.cs b/solution/0007.Reverse Integer/Solution.cs new file mode 100644 index 0000000000000..eff0ff2acbc05 --- /dev/null +++ b/solution/0007.Reverse Integer/Solution.cs @@ -0,0 +1,15 @@ +public class Solution { + public int Reverse(int x) { + var negative = x < 0; + if (negative) x = -x; + long result = 0; + while (x > 0) + { + result = (result * 10) + x % 10; + x /= 10; + } + if (negative) result = -result; + if (result > int.MaxValue || result < int.MinValue) result = 0; + return (int) result; + } +} \ No newline at end of file diff --git a/solution/0008.String to Integer (atoi)/Solution.cs b/solution/0008.String to Integer (atoi)/Solution.cs new file mode 100644 index 0000000000000..dc30aefb9e777 --- /dev/null +++ b/solution/0008.String to Integer (atoi)/Solution.cs @@ -0,0 +1,46 @@ +// https://leetcode.com/problems/string-to-integer-atoi/ + +public partial class Solution +{ + public int MyAtoi(string str) + { + int i = 0; + long result = 0; + bool minus = false; + while (i < str.Length && char.IsWhiteSpace(str[i])) + { + ++i; + } + if (i < str.Length) + { + if (str[i] == '+') + { + ++i; + } + else if (str[i] == '-') + { + minus = true; + ++i; + } + } + while (i < str.Length && char.IsDigit(str[i])) + { + result = result * 10 + str[i] - '0'; + if (result > int.MaxValue) + { + break; + } + ++i; + } + if (minus) result = -result; + if (result > int.MaxValue) + { + result = int.MaxValue; + } + if (result < int.MinValue) + { + result = int.MinValue; + } + return (int)result; + } +} \ No newline at end of file diff --git a/solution/0010.Regular Expression Matching/Solution.cs b/solution/0010.Regular Expression Matching/Solution.cs new file mode 100644 index 0000000000000..248587abd3160 --- /dev/null +++ b/solution/0010.Regular Expression Matching/Solution.cs @@ -0,0 +1,47 @@ +public class Solution { + public bool IsMatch(string s, string p) { + var f = new bool[s.Length + 1, p.Length + 1]; + f[0, 0] = true; + for (var i = 0; i <= s.Length; ++i) + { + for (var j = 0; j <= p.Length; ++j) + { + if (i != 0 || j != 0) + { + if (j == 0) + { + f[i, j] = false; + } + else if (i == 0) + { + if (p[j - 1] == '*') + { + f[i, j] = f[i, j - 2]; + } + else + { + f[i, j] = false; + } + } + else + { + if (p[j - 1] == '.') + { + f[i, j] = f[i - 1, j - 1]; + } + else if (p[j - 1] == '*') + { + f[i, j] = f[i - 1, j] && (s[i - 1] == p[j - 2] || p[j - 2] == '.') || f[i, j - 2]; + } + else + { + f[i, j] = f[i - 1, j - 1] && s[i - 1] == p[j - 1]; + } + } + } + } + } + + return f[s.Length, p.Length]; + } +} \ No newline at end of file diff --git a/solution/0014.Longest Common Prefix/Solution.cs b/solution/0014.Longest Common Prefix/Solution.cs new file mode 100644 index 0000000000000..40ea7dc086346 --- /dev/null +++ b/solution/0014.Longest Common Prefix/Solution.cs @@ -0,0 +1,22 @@ +using System.Text; +using System.Linq; + +public class Solution { + public string LongestCommonPrefix(string[] strs) { + if (strs.Length == 0) return string.Empty; + var sb = new StringBuilder(); + for (var i = 0; i < strs[0].Length; ++i) + { + var ch = strs[0][i]; + if (strs.All(str => str.Length > i && str[i] == ch)) + { + sb.Append(ch); + } + else + { + break; + } + } + return sb.ToString(); + } +} \ No newline at end of file diff --git a/solution/0015.3Sum/Solution.cs b/solution/0015.3Sum/Solution.cs new file mode 100644 index 0000000000000..369231d76fd58 --- /dev/null +++ b/solution/0015.3Sum/Solution.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +public class ThreeSumComparer : IEqualityComparer> +{ + public bool Equals(IList left, IList right) + { + return left[0] == right[0] && left[1] == right[1] && left[2] == right[2]; + } + + public int GetHashCode(IList obj) + { + return (obj[0] ^ obj[1] ^ obj[2]).GetHashCode(); + } +} + +public class Solution { + public IList> ThreeSum(int[] nums) { + Array.Sort(nums); + var results = new HashSet>(new ThreeSumComparer()); + + var cIndex = Array.BinarySearch(nums, 0); + if (cIndex < 0) cIndex = ~cIndex; + while (cIndex < nums.Length) + { + var c = nums[cIndex]; + var aIndex = 0; + var bIndex = cIndex - 1; + while (aIndex < bIndex) + { + if (nums[aIndex] + nums[bIndex] + c < 0) + { + var step = 1; + while (aIndex + step < bIndex && nums[aIndex + step] + nums[bIndex] + c < 0) + { + aIndex += step; + step *= 2; + } + step /= 2; + while (step > 0) + { + if (aIndex + step < bIndex && nums[aIndex + step] + nums[bIndex] + c < 0) + { + aIndex += step; + } + step /= 2; + } + } + + if (nums[aIndex] + nums[bIndex] + c > 0) + { + var step = 1; + while (aIndex < bIndex - step && nums[aIndex] + nums[bIndex - step] + c > 0) + { + bIndex -= step; + step *= 2; + } + step /= 2; + while (step > 0) + { + if (aIndex < bIndex - step && nums[aIndex] + nums[bIndex - step] + c > 0) + { + bIndex -= step; + } + step /= 2; + } + } + + if (nums[aIndex] + nums[bIndex] + c == 0) + { + var list = new List { nums[aIndex], nums[bIndex], c }; + results.Add(list); + ++aIndex; + --bIndex; + } + else if (nums[aIndex] + nums[bIndex] + c < 0) + { + ++aIndex; + } + else + { + --bIndex; + } + } + ++cIndex; + } + + return results.ToList(); + } +} \ No newline at end of file diff --git a/solution/0017.Letter Combinations of a Phone Number/Solution.cs b/solution/0017.Letter Combinations of a Phone Number/Solution.cs new file mode 100644 index 0000000000000..fa574f8625ba9 --- /dev/null +++ b/solution/0017.Letter Combinations of a Phone Number/Solution.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; +using System.Linq; + +public class Solution { + private static string[] chars = { + "abc", + "def", + "ghi", + "jkl", + "mno", + "pqrs", + "tuv", + "wxyz" + }; + + public IList LetterCombinations(string digits) { + var numbers = digits.Where(d => d >= '2' && d <= '9').Select(d => d - '2').ToArray(); + var states = new int[numbers.Length]; + var results = new List(); + if (numbers.Length == 0) return results; + while (true) { + results.Add(new string(states.Select((s, j) => chars[numbers[j]][s]).ToArray())); + var i = states.Length - 1; + ++states[i]; + while (i >= 0 && states[i] == chars[numbers[i]].Length) + { + states[i] = 0; + --i; + if (i >= 0) + { + ++states[i]; + } + } + if (i < 0) return results; + } + } +} \ No newline at end of file diff --git a/solution/0018.4Sum/Solution.cs b/solution/0018.4Sum/Solution.cs new file mode 100644 index 0000000000000..fa9a6c718f943 --- /dev/null +++ b/solution/0018.4Sum/Solution.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +class FourSumComparer : IEqualityComparer> +{ + public bool Equals(IList left, IList right) + { + return left[0] == right[0] && left[1] == right[1] && left[2] == right[2] && left[3] == right[3]; + } + + public int GetHashCode(IList obj) + { + return (obj[0] ^ obj[1] ^ obj[2] ^ obj[3]).GetHashCode(); + } +} + +public class Solution { + public IList> FourSum(int[] nums, int target) { + Array.Sort(nums); + var results = new HashSet>(new FourSumComparer()); + for (var i = 0; i < nums.Length; ++i) + { + for (var j = i + 1; j < nums.Length; ++j) + { + var sum = target - nums[i] - nums[j]; + var k = j + 1; + var l = nums.Length - 1; + var step = (int)Math.Sqrt(nums.Length); + while (k < l) + { + while (k + step < l && nums[k + step] + nums[l] < sum) + { + k += step; + } + while (k < l && nums[k] + nums[l] < sum) + { + k += 1; + } + if (k < l && nums[k] + nums[l] == sum) + { + results.Add(new [] { nums[i], nums[j], nums[k], nums[l] }); + ++k; + } + while (k + step < l && nums[k] + nums[l - step] > sum) + { + l -= step; + } + while (k < l && nums[k] + nums[l] > sum) + { + l -= 1; + } + if (k < l && nums[k] + nums[l] == sum) + { + results.Add(new [] { nums[i], nums[j], nums[k], nums[l] }); + --l; + } + } + } + } + + return results.ToList(); + } +} \ No newline at end of file diff --git a/solution/0023.Merge k Sorted Lists/Solution.cs b/solution/0023.Merge k Sorted Lists/Solution.cs new file mode 100644 index 0000000000000..d64f94a06b4fc --- /dev/null +++ b/solution/0023.Merge k Sorted Lists/Solution.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +class Comparer : IComparer> +{ + public int Compare(Tuple left, Tuple right) + { + var result = left.Item1.val.CompareTo(right.Item1.val); + if (result == 0) + { + result = left.Item2.CompareTo(right.Item2); + } + return result; + } +} + +public class Solution { + public ListNode MergeKLists(ListNode[] lists) { + var heap = new SortedSet>(new Comparer()); + for (var i = 0; i < lists.Length; ++i) + { + if (lists[i] != null) heap.Add(Tuple.Create(lists[i], i)); + } + ListNode head = null; + ListNode current = null; + while (heap.Any()) + { + var min = heap.Min; + heap.Remove(min); + if (min.Item1.next != null) heap.Add(Tuple.Create(min.Item1.next, min.Item2)); + if (head == null) + { + head = min.Item1; + current = head; + } + else + { + current.next = min.Item1; + current = current.next; + } + } + return head; + } +} \ No newline at end of file diff --git a/solution/0025.Reverse Nodes in k-Group/Solution.cs b/solution/0025.Reverse Nodes in k-Group/Solution.cs new file mode 100644 index 0000000000000..4deadf8bd4820 --- /dev/null +++ b/solution/0025.Reverse Nodes in k-Group/Solution.cs @@ -0,0 +1,52 @@ +public class Solution { + public ListNode ReverseKGroup(ListNode head, int k) { + if (k < 2) return head; + ListNode newHead = null; + ListNode newTail = null; + var current = head; + while (current != null) + { + ListNode segmentHead = null; + ListNode segmentTail = null; + var count = 0; + while (current != null && count < k) + { + if (segmentHead == null) segmentHead = current; + segmentTail = current; + current = current.next; + ++count; + } + segmentTail.next = null; + if (count == k) + { + segmentTail = segmentHead; + segmentHead = ReverseList(segmentHead); + } + if (newHead == null) + { + newHead = segmentHead; + newTail = segmentTail; + } + else + { + newTail.next = segmentHead; + newTail = segmentTail; + } + } + return newHead; + } + + private ListNode ReverseList(ListNode head) + { + var current = head; + head = null; + while (current != null) + { + var next = current.next; + current.next = head; + head = current; + current = next; + } + return head; + } +} \ No newline at end of file diff --git a/solution/0026.Remove Duplicates from Sorted Array/Solution.cs b/solution/0026.Remove Duplicates from Sorted Array/Solution.cs new file mode 100644 index 0000000000000..359db003d4019 --- /dev/null +++ b/solution/0026.Remove Duplicates from Sorted Array/Solution.cs @@ -0,0 +1,16 @@ +public class Solution { + public int RemoveDuplicates(int[] nums) { + if (nums.Length < 2) return nums.Length; + var i = 0; + var j = 1; + while (j < nums.Length) + { + if (nums[i] != nums[j]) + { + nums[++i] = nums[j]; + } + ++j; + } + return i + 1; + } +} \ No newline at end of file diff --git a/solution/0028.Implement strStr()/Solution.cs b/solution/0028.Implement strStr()/Solution.cs new file mode 100644 index 0000000000000..20539523d0c4a --- /dev/null +++ b/solution/0028.Implement strStr()/Solution.cs @@ -0,0 +1,14 @@ +public class Solution { + public int StrStr(string haystack, string needle) { + for (var i = 0; i < haystack.Length - needle.Length + 1; ++i) + { + var j = 0; + for (; j < needle.Length; ++j) + { + if (haystack[i + j] != needle[j]) break; + } + if (j == needle.Length) return i; + } + return -1; + } +} \ No newline at end of file diff --git a/solution/0029.Divide Two Integers/Solution.cs b/solution/0029.Divide Two Integers/Solution.cs new file mode 100644 index 0000000000000..f907d18374483 --- /dev/null +++ b/solution/0029.Divide Two Integers/Solution.cs @@ -0,0 +1,49 @@ +public class Solution { + public int Divide(int dividend, int divisor) { + return (int)DivideInternal(dividend, divisor); + } + + public long GetHighestBit(long x) + { + if (x == 0) return 0; + long k = 0x80000000; + while ((x & k) == 0) + { + k >>= 1; + } + return k; + } + + public long DivideInternal(long dividend, long divisor) + { + int sign = (dividend > 0) ^ (divisor > 0) ? -1 : 1; + if (dividend < 0) dividend = -dividend; + if (divisor < 0) divisor = -divisor; + + long result = 0; + long pointer = GetHighestBit(dividend); + long currentHeader = 1; + dividend = dividend ^ pointer; + while (pointer > 0) + { + result <<= 1; + if (currentHeader >= divisor) + { + ++result; + currentHeader -= divisor; + } + pointer >>= 1; + bool nextIsOne = (dividend & pointer) != 0; + currentHeader = (currentHeader << 1) + (nextIsOne ? 1 : 0); + dividend = dividend ^ (nextIsOne ? pointer : 0); + } + + result = sign * result; + + if (result > int.MaxValue || result < int.MinValue) + { + return int.MaxValue; + } + return result; + } +} \ No newline at end of file diff --git a/solution/0030.Substring with Concatenation of All Words/Solution.cs b/solution/0030.Substring with Concatenation of All Words/Solution.cs new file mode 100644 index 0000000000000..20f85aa5072d6 --- /dev/null +++ b/solution/0030.Substring with Concatenation of All Words/Solution.cs @@ -0,0 +1,57 @@ +using System.Collections.Generic; + +public class Solution { + public IList FindSubstring(string s, string[] words) { + if (words.Length == 0) return new List(); + + var wordsDict = new Dictionary(); + foreach (var word in words) + { + if (!wordsDict.ContainsKey(word)) + { + wordsDict.Add(word, 1); + } + else + { + ++wordsDict[word]; + } + } + + var wordOfS = new string[s.Length]; + var wordLength = words[0].Length; + var wordCount = words.Length; + for (var i = 0; i <= s.Length - wordLength; ++i) + { + var substring = s.Substring(i, wordLength); + if (wordsDict.ContainsKey(substring)) + { + wordOfS[i] = substring; + } + } + + var result = new List(); + for (var i = 0; i <= s.Length - wordLength * wordCount; ++i) + { + var tempDict = new Dictionary(wordsDict); + var tempCount = 0; + for (var j = i; j <= i + wordLength * (wordCount - 1); j += wordLength) + { + if (wordOfS[j] != null && tempDict[wordOfS[j]] > 0) + { + --tempDict[wordOfS[j]]; + ++tempCount; + } + else + { + break; + } + } + if (tempCount == wordCount) + { + result.Add(i); + } + } + + return result; + } +} \ No newline at end of file diff --git a/solution/0031.Next Permutation/Solution.cs b/solution/0031.Next Permutation/Solution.cs new file mode 100644 index 0000000000000..1a38df58dfb82 --- /dev/null +++ b/solution/0031.Next Permutation/Solution.cs @@ -0,0 +1,26 @@ +public class Solution { + public void NextPermutation(int[] nums) { + var index1 = -1; + var index2 = 0; + for (var i = 1; i < nums.Length; ++i) + { + if (nums[i - 1] < nums[i]) + { + index1 = i - 1; + index2 = i; + } + else if (index1 >= 0 && nums[index1] < nums[i]) + { + index2 = i; + } + } + + if (index1 >= 0) + { + var temp = nums[index1]; + nums[index1] = nums[index2]; + nums[index2] = temp; + } + System.Array.Sort(nums, index1 + 1, nums.Length - index1 - 1); + } +} \ No newline at end of file diff --git a/solution/0032.Longest Valid Parentheses/Solution.cs b/solution/0032.Longest Valid Parentheses/Solution.cs new file mode 100644 index 0000000000000..d482cbfe63766 --- /dev/null +++ b/solution/0032.Longest Valid Parentheses/Solution.cs @@ -0,0 +1,40 @@ +using System.Collections.Generic; + +public class Solution { + public int LongestValidParentheses(string s) { + var result = 0; + var baseCount = 0; + var stack = new Stack(); + foreach (var ch in s) + { + switch (ch) + { + case '(': + stack.Push(1); + break; + case ')': + if (stack.Count > 0) + { + var count = stack.Pop() + 1; + if (stack.Count > 0) + { + count += stack.Pop(); + stack.Push(count); + if (count - 1 > result) result = count - 1; + } + else + { + baseCount += count; + if (baseCount > result) result = baseCount; + } + } + else + { + baseCount = 0; + } + break; + } + } + return result; + } +} \ No newline at end of file diff --git a/solution/0037.Sudoku Solver/Solution.cs b/solution/0037.Sudoku Solver/Solution.cs new file mode 100644 index 0000000000000..c5b3967017708 --- /dev/null +++ b/solution/0037.Sudoku Solver/Solution.cs @@ -0,0 +1,131 @@ +public class Solution { + public void SolveSudoku(char[][] board) { + this.board = new ushort?[9,9]; + for (var i = 0; i < 9; ++i) + { + for (var j = 0; j < 9; ++j) + { + if (board[i][j] != '.') + { + this.board[i, j] = (ushort) (1 << (board[i][j] - '0' - 1)); + } + } + } + + if (SolveSudoku(0, 0)) + { + for (var i = 0; i < 9; ++i) + { + for (var j = 0; j < 9; ++j) + { + if (board[i][j] == '.') + { + board[i][j] = '0'; + while (this.board[i, j].Value != 0) + { + board[i][j] = (char)(board[i][j] + 1); + this.board[i, j] >>= 1; + } + } + } + } + } + } + + private ushort?[,] board; + + private bool ValidateHorizontalRule(int row) + { + ushort temp = 0; + for (var i = 0; i < 9; ++i) + { + if (board[row, i].HasValue) + { + if ((temp | board[row, i].Value) == temp) + { + return false; + } + temp |= board[row, i].Value; + } + } + return true; + } + + private bool ValidateVerticalRule(int column) + { + ushort temp = 0; + for (var i = 0; i < 9; ++i) + { + if (board[i, column].HasValue) + { + if ((temp | board[i, column].Value) == temp) + { + return false; + } + temp |= board[i, column].Value; + } + } + return true; + } + + private bool ValidateBlockRule(int row, int column) + { + var startRow = row / 3 * 3; + var startColumn = column / 3 * 3; + ushort temp = 0; + for (var i = startRow; i < startRow + 3; ++i) + { + for (var j = startColumn; j < startColumn + 3; ++j) + { + if (board[i, j].HasValue) + { + if ((temp | board[i, j].Value) == temp) + { + return false; + } + temp |= board[i, j].Value; + } + } + } + return true; + } + + private bool SolveSudoku(int i, int j) + { + while (true) + { + if (j == 9) + { + ++i; + j = 0; + } + if (i == 9) + { + return true; + } + if (board[i, j].HasValue) + { + ++j; + } + else + { + break; + } + } + + ushort stop = 1 << 9; + for (ushort t = 1; t != stop; t <<= 1) + { + board[i, j] = t; + if (ValidateHorizontalRule(i) && ValidateVerticalRule(j) && ValidateBlockRule(i, j)) + { + if (SolveSudoku(i, j + 1)) + { + return true; + } + } + } + board[i, j] = null; + return false; + } +} \ No newline at end of file diff --git a/solution/0038.Count and Say/Solution.cs b/solution/0038.Count and Say/Solution.cs new file mode 100644 index 0000000000000..ff91620e2f282 --- /dev/null +++ b/solution/0038.Count and Say/Solution.cs @@ -0,0 +1,37 @@ +using System.Text; +public class Solution { + public string CountAndSay(int n) { + var s = "1"; + while (n > 1) + { + var sb = new StringBuilder(); + var lastChar = '1'; + var count = 0; + foreach (var ch in s) + { + if (count > 0 && lastChar == ch) + { + ++count; + } + else + { + if (count > 0) + { + sb.Append(count); + sb.Append(lastChar); + } + lastChar = ch; + count = 1; + } + } + if (count > 0) + { + sb.Append(count); + sb.Append(lastChar); + } + s = sb.ToString(); + --n; + } + return s; + } +} \ No newline at end of file diff --git a/solution/0039.Combination Sum/Solution.cs b/solution/0039.Combination Sum/Solution.cs new file mode 100644 index 0000000000000..6e618652e0de6 --- /dev/null +++ b/solution/0039.Combination Sum/Solution.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +public class Solution +{ + public IList> CombinationSum(int[] candidates, int target) + { + Array.Sort(candidates); + candidates = candidates.Distinct().ToArray(); + + var paths = new List[target + 1]; + paths[0] = new List(); + foreach (var c in candidates) + { + for (var j = c; j <= target; ++j) + { + if (paths[j - c] != null) + { + if (paths[j] == null) + { + paths[j] = new List(); + } + paths[j].Add(c); + } + } + } + + var results = new List>(); + if (paths[target] != null) GenerateResults(results, new Stack(), paths, target, paths[target].Count - 1); + return results; + } + + private void GenerateResults(IList> results, Stack result, List[] paths, int remaining, + int maxIndex) + { + if (remaining == 0) + { + results.Add(new List(result)); + return; + } + for (var i = maxIndex; i >= 0; --i) + { + var value = paths[remaining][i]; + result.Push(value); + var nextMaxIndex = paths[remaining - value].BinarySearch(value); + if (nextMaxIndex < 0) + { + nextMaxIndex = ~nextMaxIndex - 1; + } + GenerateResults(results, result, paths, remaining - value, nextMaxIndex); + result.Pop(); + } + } +} \ No newline at end of file diff --git a/solution/0040.Combination Sum II/Solution.cs b/solution/0040.Combination Sum II/Solution.cs new file mode 100644 index 0000000000000..8bf55da400df0 --- /dev/null +++ b/solution/0040.Combination Sum II/Solution.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +public class Solution +{ + public IList> CombinationSum2(int[] candidates, int target) + { + var dict = new SortedDictionary(candidates.GroupBy(c => c).ToDictionary(g => g.Key, g => g.Count())); + var paths = new List>[target + 1]; + paths[0] = new List>(); + foreach (var pair in dict) + { + for (var j = target; j >= 0; --j) + { + for (var k = 1; k <= pair.Value && j - pair.Key * k >= 0; ++k) + { + if (paths[j - pair.Key * k] != null) + { + if (paths[j] == null) + { + paths[j] = new List>(); + } + paths[j].Add(Tuple.Create(pair.Key, k)); + } + } + } + } + + var results = new List>(); + if (paths[target] != null) GenerateResults(results, new Stack(), paths, target, paths[target].Count - 1); + return results; + } + + private void GenerateResults(IList> results, Stack result, List>[] paths, int remaining, + int maxIndex) + { + if (remaining == 0) + { + results.Add(new List(result)); + return; + } + for (var i = maxIndex; i >= 0; --i) + { + var path = paths[remaining][i]; + for (var j = 0; j < path.Item2; ++j) + { + result.Push(path.Item1); + } + var nextMaxIndex = paths[remaining - path.Item1 * path.Item2].BinarySearch(Tuple.Create(path.Item1, int.MinValue), Comparer.Instance); + nextMaxIndex = ~nextMaxIndex - 1; + GenerateResults(results, result, paths, remaining - path.Item1 * path.Item2, nextMaxIndex); + for (var j = 0; j < path.Item2; ++j) + { + result.Pop(); + } + } + } +} + +class Comparer : IComparer> +{ + public int Compare(Tuple x, Tuple y) + { + if (x.Item1 < y.Item1) return -1; + if (x.Item1 > y.Item1) return 1; + return x.Item2.CompareTo(y.Item2); + } + + public static Comparer Instance = new Comparer(); +} \ No newline at end of file diff --git a/solution/0041.First Missing Positive/Solution.cs b/solution/0041.First Missing Positive/Solution.cs new file mode 100644 index 0000000000000..c7122e6bd716a --- /dev/null +++ b/solution/0041.First Missing Positive/Solution.cs @@ -0,0 +1,35 @@ +public class Solution { + public int FirstMissingPositive(int[] nums) { + var i = 0; + while (i < nums.Length) + { + if (nums[i] > 0 && nums[i] <= nums.Length) + { + var index = nums[i] -1; + if (index != i && nums[index] != nums[i]) + { + var temp = nums[i]; + nums[i] = nums[index]; + nums[index] = temp; + } + else + { + ++i; + } + } + else + { + ++i; + } + } + + for (i = 0; i < nums.Length; ++i) + { + if (nums[i] != i + 1) + { + return i + 1; + } + } + return nums.Length + 1; + } +} \ No newline at end of file diff --git a/solution/0043.Multiply Strings/Solution.cs b/solution/0043.Multiply Strings/Solution.cs new file mode 100644 index 0000000000000..f73a98c15225b --- /dev/null +++ b/solution/0043.Multiply Strings/Solution.cs @@ -0,0 +1,36 @@ +using System.Text; + +public class Solution { + public string Multiply(string num1, string num2) { + var digits = new int[num1.Length + num2.Length]; + for (var i = 0; i < num1.Length; ++i) + { + for (var j = 0; j < num2.Length; ++j) + { + var digit1 = num1[num1.Length - i - 1] - '0'; + var digit2 = num2[num2.Length - j - 1] - '0'; + var product = digit1 * digit2; + digits[i + j] += product; + } + } + + var carry = 0; + for (var i = 0; i < digits.Length; ++i) + { + digits[i] += carry; + carry = digits[i] / 10; + digits[i] %= 10; + } + + var sb = new StringBuilder(); + for (var i = digits.Length - 1; i >= 0; --i) + { + if (digits[i] > 0 || sb.Length > 0) + { + sb.Append((char)(digits[i] + '0')); + } + } + if (sb.Length == 0) sb.Append('0'); + return sb.ToString(); + } +} \ No newline at end of file diff --git a/solution/0044.Wildcard Matching/Solution.cs b/solution/0044.Wildcard Matching/Solution.cs new file mode 100644 index 0000000000000..d67136b7bf272 --- /dev/null +++ b/solution/0044.Wildcard Matching/Solution.cs @@ -0,0 +1,43 @@ +using System.Linq; + +public class Solution { + public bool IsMatch(string s, string p) { + if (p.Count(ch => ch != '*') > s.Length) + { + return false; + } + + bool[,] f = new bool[s.Length + 1, p.Length + 1]; + bool[] d = new bool[s.Length + 1]; // d[i] means f[0, j] || f[1, j] || ... || f[i, j] + for (var j = 0; j <= p.Length; ++j) + { + d[0] = j == 0 ? true : d[0] && p[j - 1] == '*'; + for (var i = 0; i <= s.Length; ++i) + { + if (j == 0) + { + f[i, j] = i == 0; + continue; + } + + if (p[j - 1] == '*') + { + if (i > 0) + { + d[i] = f[i, j - 1] || d[i - 1]; + } + f[i, j] = d[i]; + } + else if (p[j - 1] == '?') + { + f[i, j] = i > 0 && f[i - 1, j - 1]; + } + else + { + f[i, j] = i > 0 && f[i - 1, j - 1] && s[i - 1] == p[j - 1]; + } + } + } + return f[s.Length, p.Length]; + } +} \ No newline at end of file diff --git a/solution/0045.Jump Game II/Solution.cs b/solution/0045.Jump Game II/Solution.cs new file mode 100644 index 0000000000000..4002aa8575843 --- /dev/null +++ b/solution/0045.Jump Game II/Solution.cs @@ -0,0 +1,29 @@ +using System; + +public class Solution { + public int Jump(int[] nums) { + var steps = 0; + var maxJump = 0; + var i = 0; + while (maxJump + 1 < nums.Length) + { + var newMaxJump = maxJump; + for (var j = i; j < nums.Length && j <= maxJump; ++j) + { + newMaxJump = Math.Max(newMaxJump, j + nums[j]); + } + i = maxJump + 1; + if (newMaxJump > maxJump) + { + maxJump = newMaxJump; + ++steps; + } + else + { + break; + } + } + if (maxJump + 1 >= nums.Length) return steps; + return -1; + } +} \ No newline at end of file diff --git a/solution/0046.Permutations/Solution.cs b/solution/0046.Permutations/Solution.cs new file mode 100644 index 0000000000000..64ed61f220c88 --- /dev/null +++ b/solution/0046.Permutations/Solution.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; +using System.Linq; + +public class Solution { + public IList> Permute(int[] nums) { + var results = new List>(); + var temp = new List(); + var visited = new bool[nums.Length]; + Search(nums, visited, temp, results); + return results; + } + + private void Search(int[] nums, bool[] visited, IList temp, IList> results) + { + int count = 0; + for (var i = 0; i < nums.Length; ++i) + { + if (visited[i]) continue; + ++count; + temp.Add(nums[i]); + visited[i] = true; + Search(nums, visited, temp, results); + temp.RemoveAt(temp.Count - 1); + visited[i] = false; + } + if (count == 0 && temp.Any()) + { + results.Add(new List(temp)); + } + } +} \ No newline at end of file diff --git a/solution/0047.Permutations II/Solution.cs b/solution/0047.Permutations II/Solution.cs new file mode 100644 index 0000000000000..6a13dfb19a68b --- /dev/null +++ b/solution/0047.Permutations II/Solution.cs @@ -0,0 +1,38 @@ +using System.Collections.Generic; +using System.Linq; + +public class Solution { + public IList> PermuteUnique(int[] nums) { + var results = new List>(); + var temp = new List(); + var count = nums.GroupBy(n => n).ToDictionary(g => g.Key, g => g.Count()); + Search(count, temp, results); + return results; + } + + private void Search(Dictionary count, IList temp, IList> results) + { + if (!count.Any() && temp.Any()) + { + results.Add(new List(temp)); + return; + } + var keys = count.Keys.ToList(); + foreach (var key in keys) + { + temp.Add(key); + --count[key]; + if (count[key] == 0) count.Remove(key); + Search(count, temp, results); + temp.RemoveAt(temp.Count - 1); + if (count.ContainsKey(key)) + { + ++count[key]; + } + else + { + count[key] = 1; + } + } + } +} \ No newline at end of file diff --git a/solution/0049.Group Anagrams/Solution.cs b/solution/0049.Group Anagrams/Solution.cs new file mode 100644 index 0000000000000..a3bf6ba358ee4 --- /dev/null +++ b/solution/0049.Group Anagrams/Solution.cs @@ -0,0 +1,55 @@ +using System.Collections.Generic; + +public class Comparer : IEqualityComparer +{ + public bool Equals(string left, string right) + { + if (left.Length != right.Length) return false; + + var leftCount = new int[26]; + foreach (var ch in left) + { + ++leftCount[ch - 'a']; + } + + var rightCount = new int[26]; + foreach (var ch in right) + { + var index = ch - 'a'; + if (++rightCount[index] > leftCount[index]) return false; + } + + return true; + } + + public int GetHashCode(string obj) + { + var hashCode = 0; + for (int i = 0; i < obj.Length; ++i) + { + hashCode ^= 1 << (obj[i] - 'a'); + } + return hashCode; + } +} + +public class Solution { + public IList> GroupAnagrams(string[] strs) { + var dict = new Dictionary>(new Comparer()); + foreach (var str in strs) + { + List list; + if (!dict.TryGetValue(str, out list)) + { + list = new List(); + dict.Add(str, list); + } + list.Add(str); + } + foreach (var list in dict.Values) + { + list.Sort(); + } + return new List>(dict.Values); + } +} \ No newline at end of file diff --git a/solution/0051.N-Queens/Solution.cs b/solution/0051.N-Queens/Solution.cs new file mode 100644 index 0000000000000..fb8a710a1c867 --- /dev/null +++ b/solution/0051.N-Queens/Solution.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; +using System.Text; + +public class Solution { + private IList> results = new List>(); + private int n; + + public IList> SolveNQueens(int n) { + this.n = n; + Search(new List(), 0, 0, 0); + return results; + } + + private void Search(IList state, int left, int right, int vertical) + { + if (state.Count == n) + { + Print(state); + return; + } + int available = ~(left | right | vertical) & ((1 << n) - 1); + while (available != 0) + { + int x = available & -available; + state.Add(x); + Search(state, (left | x ) << 1, (right | x ) >> 1, vertical | x); + state.RemoveAt(state.Count - 1); + available &= ~x; + } + } + + private void Print(IList state) + { + var result = new List(); + var sb = new StringBuilder(n); + foreach (var s in state) + { + var x = s; + for (var i = 0; i < n; ++i) + { + sb.Append((x & 1) != 0 ? 'Q': '.'); + x >>= 1; + } + result.Add(sb.ToString()); + sb.Clear(); + } + results.Add(result); + } +} \ No newline at end of file diff --git a/solution/0054.Spiral Matrix/Solution.cs b/solution/0054.Spiral Matrix/Solution.cs new file mode 100644 index 0000000000000..66d3ce41e82fc --- /dev/null +++ b/solution/0054.Spiral Matrix/Solution.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; + +public class Solution { + public IList SpiralOrder(int[][] matrix) { + var lenI = matrix.Length; + var lenJ = lenI == 0 ? 0 : matrix[0].Length; + var result = new List(lenI * lenJ); + var rounds = (Math.Min(lenI, lenJ) + 1) / 2; + for (var r = 0; r < rounds; ++r) + { + if (lenI - r * 2 == 1) + { + for (var j = r; j < lenJ - r; ++j) + { + result.Add(matrix[r][j]); + } + } + else if (lenJ - r * 2 == 1) + { + for (var i = r; i < lenI - r; ++i) + { + result.Add(matrix[i][r]); + } + } + else + { + for (var j = r; j < lenJ - r - 1; ++j) + { + result.Add(matrix[r][j]); + } + for (var i = r; i < lenI - r - 1; ++i) + { + result.Add(matrix[i][lenJ - r - 1]); + } + for (var j = lenJ - r - 1; j > r; --j) + { + result.Add(matrix[lenI - r - 1][j]); + } + for (var i = lenI - r - 1; i > r; --i) + { + result.Add(matrix[i][r]); + } + } + } + return result; + } +} \ No newline at end of file diff --git a/solution/0055.Jump Game/Solution.cs b/solution/0055.Jump Game/Solution.cs new file mode 100644 index 0000000000000..6d91e1e7c4006 --- /dev/null +++ b/solution/0055.Jump Game/Solution.cs @@ -0,0 +1,19 @@ +using System; + +public class Solution { + public bool CanJump(int[] nums) { + var maxJump = 0; + for (var i = 0; i < nums.Length; ++i) + { + if (i <= maxJump) + { + maxJump = Math.Max(maxJump, i + nums[i]); + } + else + { + return false; + } + } + return true; + } +} \ No newline at end of file diff --git a/solution/0056.Merge Intervals/Solution.cs b/solution/0056.Merge Intervals/Solution.cs new file mode 100644 index 0000000000000..685b8b562cb0f --- /dev/null +++ b/solution/0056.Merge Intervals/Solution.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; +using System.Linq; + +public class Solution { + public int[][] Merge(int[][] intervals) { + var result = new List(); + foreach (var interval in intervals.OrderBy(i => i[0])) + { + if (!result.Any()) + { + result.Add(interval); + } + else + { + var last = result.Last(); + if (last[1] < interval[0]) + { + result.Add(interval); + } + else if (last[1] < interval[1]) + { + last[1] = interval[1]; + } + } + } + return result.ToArray(); + } +} \ No newline at end of file diff --git a/solution/0057.Insert Interval/Solution.cs b/solution/0057.Insert Interval/Solution.cs new file mode 100644 index 0000000000000..7a01f74ecfec9 --- /dev/null +++ b/solution/0057.Insert Interval/Solution.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; + +public class Solution { + public int[][] Insert(int[][] intervals, int[] newInterval) { + var result = new List(); + var i = 0; + + while (i < intervals.Length && intervals[i][1] < newInterval[0]) + { + result.Add(intervals[i++]); + } + + while (i < intervals.Length && intervals[i][0] <= newInterval[1] && intervals[i][1] >= newInterval[0]) + { + newInterval[0] = Math.Min(intervals[i][0], newInterval[0]); + newInterval[1] = Math.Max(intervals[i][1], newInterval[1]); + ++i; + } + result.Add(newInterval); + + while (i < intervals.Length) + { + result.Add(intervals[i++]); + } + + return result.ToArray(); + } +} \ No newline at end of file diff --git a/solution/0060.Permutation Sequence/Solution.cs b/solution/0060.Permutation Sequence/Solution.cs new file mode 100644 index 0000000000000..5446c2c0783bd --- /dev/null +++ b/solution/0060.Permutation Sequence/Solution.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using System.Linq; +using System.Text; + +public class Solution { + public string GetPermutation(int n, int k) { + --k; + var factorial = Enumerable.Range(0, n).Select(i => Enumerable.Range(1, i).Aggregate(1, (agg, x) => agg * x)).ToArray(); + var numbers = new SortedSet(Enumerable.Range(1, n)); + var sb = new StringBuilder(); + while (sb.Length < n) + { + var f = factorial[numbers.Count - 1]; + var index = k / f; + var number = numbers.ElementAt(index); + sb.Append(number); + numbers.Remove(number); + k %= f; + } + return sb.ToString(); + } +} diff --git a/solution/0061.Rotate List/Solution.cs b/solution/0061.Rotate List/Solution.cs new file mode 100644 index 0000000000000..61a01fbeb06c9 --- /dev/null +++ b/solution/0061.Rotate List/Solution.cs @@ -0,0 +1,29 @@ +public class Solution { + public ListNode RotateRight(ListNode head, int k) { + var length = 0; + var temp = head; + var last = head; + while (temp != null) + { + ++length; + last = temp; + temp = temp.next; + } + if (length == 0) return null; + + k %= length; + if (k == 0) return head; + k = length - k; + + ListNode kNode = head; + for (var i = 1; i < k; ++i) + { + kNode = kNode.next; + } + + last.next = head; + head = kNode.next; + kNode.next = null; + return head; + } +} \ No newline at end of file diff --git a/solution/0065.Valid/Solution.cs b/solution/0065.Valid/Solution.cs new file mode 100644 index 0000000000000..04eb872a5c99f --- /dev/null +++ b/solution/0065.Valid/Solution.cs @@ -0,0 +1,12 @@ +// https://leetcode.com/problems/valid-number/ + +using System.Text.RegularExpressions; + +public partial class Solution +{ + private readonly Regex _isNumber_Regex = new Regex(@"^\s*[+-]?(\d+(\.\d*)?|\.\d+)([Ee][+-]?\d+)?\s*$"); + public bool IsNumber(string s) + { + return _isNumber_Regex.IsMatch(s); + } +} \ No newline at end of file diff --git a/solution/0067.Add Binary/Solution.cs b/solution/0067.Add Binary/Solution.cs new file mode 100644 index 0000000000000..dffa1ce39942b --- /dev/null +++ b/solution/0067.Add Binary/Solution.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; + +public class Solution { + public string AddBinary(string a, string b) { + var list = new List(Math.Max(a.Length, b.Length) + 1); + var i = a.Length - 1; + var j = b.Length - 1; + var carry = 0; + while (i >= 0 || j >= 0) + { + if (i >= 0) + { + carry += a[i] - '0'; + } + if (j >= 0) + { + carry += b[j] - '0'; + } + list.Add((char)((carry % 2) + '0')); + carry /= 2; + --i; + --j; + } + if (carry > 0) list.Add((char) (carry + '0')); + list.Reverse(); + return new string(list.ToArray()); + } +} \ No newline at end of file diff --git a/solution/0068.Text Justification/Solution.cs b/solution/0068.Text Justification/Solution.cs new file mode 100644 index 0000000000000..5df9c08e1503b --- /dev/null +++ b/solution/0068.Text Justification/Solution.cs @@ -0,0 +1,66 @@ +using System.Collections.Generic; +using System.Linq; +using System.Text; + +public class Solution { + public IList FullJustify(string[] words, int maxWidth) { + var result = new List(); + var buffer = new List(); + var sb = new StringBuilder(); + var len = 0; + + for (var i = 0; i < words.Length; ++i) + { + var newLen = words[i].Length + (len == 0 ? 0 : len + 1); + if (newLen <= maxWidth) + { + buffer.Add(words[i]); + len = newLen; + } + else + { + if (buffer.Count == 1) + { + sb.Append(buffer[0]); + sb.Append(' ', maxWidth - buffer[0].Length); + } + else + { + var spaceCount = maxWidth - len + buffer.Count - 1; + for (var j = 0; j < buffer.Count - 1; ++j) + { + sb.Append(buffer[j]); + var spaceToAdd = (spaceCount - 1) / (buffer.Count - j - 1) + 1; + sb.Append(' ', spaceToAdd); + spaceCount -= spaceToAdd; + } + sb.Append(buffer.Last()); + } + result.Add(sb.ToString()); + buffer.Clear(); + buffer.Add(words[i]); + sb.Clear(); + len = words[i].Length; + } + } + + if (buffer.Count > 0) + { + for (var j = 0; j < buffer.Count; ++j) + { + if (sb.Length > 0) + { + sb.Append(' '); + } + sb.Append(buffer[j]); + } + if (sb.Length < maxWidth) + { + sb.Append(' ', maxWidth - sb.Length); + } + result.Add(sb.ToString()); + } + + return result; + } +} \ No newline at end of file diff --git a/solution/0069.Sqrt(x)/Solution.cs b/solution/0069.Sqrt(x)/Solution.cs new file mode 100644 index 0000000000000..52ce6d182e4b1 --- /dev/null +++ b/solution/0069.Sqrt(x)/Solution.cs @@ -0,0 +1,30 @@ +public class Solution { + public int MySqrt(int x) { + long l = 0; + long r = x; + while (l < r) + { + var mid = (l + r) / 2; + if (mid * mid <= x) + { + l = mid; + if (l == mid) + { + if (r * r <= x) + { + l = r; + } + else + { + --r; + } + } + } + else + { + r = mid; + } + } + return (int) l; + } +} \ No newline at end of file diff --git a/solution/0071.Simplify Path/Solution.cs b/solution/0071.Simplify Path/Solution.cs new file mode 100644 index 0000000000000..3f47366a727c1 --- /dev/null +++ b/solution/0071.Simplify Path/Solution.cs @@ -0,0 +1,50 @@ +using System.Collections.Generic; +using System.Linq; +using System.Text; + +public class Solution { + public string SimplifyPath(string path) { + var stack = new Stack(); + var sb = new StringBuilder(); + foreach (var ch in ((IEnumerable)path).Concat(Enumerable.Repeat('/', 1))) + { + if (ch == '/') + { + if (sb.Length > 0) + { + var folder = sb.ToString(); + sb.Clear(); + switch (folder) + { + case ".": + break; + case "..": + if (stack.Any()) + { + stack.Pop(); + } + break; + default: + stack.Push(folder); + break; + } + } + } + else + { + sb.Append(ch); + } + } + + if (stack.Count == 0) + { + sb.Append('/'); + } + foreach (var folder in ((IEnumerable)stack.ToList()).Reverse()) + { + sb.Append('/'); + sb.Append(folder); + } + return sb.ToString(); + } +} \ No newline at end of file diff --git a/solution/0076.Minimum Window Substring/Solution.cs b/solution/0076.Minimum Window Substring/Solution.cs new file mode 100644 index 0000000000000..f88339cc5c8ca --- /dev/null +++ b/solution/0076.Minimum Window Substring/Solution.cs @@ -0,0 +1,71 @@ +using System.Linq; + +public class Solution { + public string MinWindow(string s, string t) { + var dict = t.Distinct().ToDictionary(ch => ch, ch => 0); + var goalDict = t.GroupBy(ch => ch).ToDictionary(g => g.Key, g => g.Count()); + var goal = goalDict.Count; + + var minI = int.MaxValue; + var minJ = 0; + var i = 0; + var j = 0; + var current = 0; + + while (true) + { + while (current < goal && i < s.Length) + { + if (dict.ContainsKey(s[i])) + { + if (++dict[s[i]] == goalDict[s[i]]) + { + ++current; + } + } + ++i; + } + + while (current == goal && j < s.Length) + { + if (dict.ContainsKey(s[j])) + { + if (dict[s[j]] == goalDict[s[j]]) + { + break; + } + else + { + --dict[s[j]]; + } + } + ++j; + } + + if (current == goal) + { + if (i - j < minI - minJ) + { + minI = i; + minJ = j; + } + --dict[s[j]]; + --current; + ++j; + } + else + { + break; + } + } + + if (minI == int.MaxValue) + { + return string.Empty; + } + else + { + return s.Substring(minJ, minI - minJ); + } + } +} \ No newline at end of file diff --git a/solution/0079.Word Search/Solution.cs b/solution/0079.Word Search/Solution.cs new file mode 100644 index 0000000000000..e084334842b85 --- /dev/null +++ b/solution/0079.Word Search/Solution.cs @@ -0,0 +1,37 @@ +public class Solution { + public bool Exist(char[][] board, string word) { + var lenI = board.Length; + var lenJ = lenI == 0 ? 0 : board[0].Length; + var visited = new bool[lenI, lenJ]; + for (var i = 0; i < lenI; ++i) + { + for (var j = 0; j < lenJ; ++j) + { + if (Search(board, visited, word, lenI, lenJ, i, j, 0)) + { + return true; + } + } + } + return false; + } + + private int[,] paths = new int[4,2] { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } }; + + private bool Search(char[][] board, bool[,] visited, string word, int lenI, int lenJ, int i, int j, int p) + { + if (p == word.Length) + { + return true; + } + if (i < 0 || i >= lenI || j < 0 || j >= lenJ) return false; + if (visited[i, j] || word[p] != board[i][j]) return false; + visited[i, j] = true; + for (var k = 0; k < 4; ++k) + { + if (Search(board, visited, word, lenI, lenJ, i + paths[k, 0], j + paths[k, 1], p + 1)) return true; + } + visited[i, j] = false; + return false; + } +} \ No newline at end of file diff --git a/solution/0080.Remove Duplicates from Sorted Array II/Solution.cs b/solution/0080.Remove Duplicates from Sorted Array II/Solution.cs new file mode 100644 index 0000000000000..dcd9e76df3e70 --- /dev/null +++ b/solution/0080.Remove Duplicates from Sorted Array II/Solution.cs @@ -0,0 +1,16 @@ +public class Solution { + public int RemoveDuplicates(int[] nums) { + if (nums.Length <= 2) return nums.Length; + var i = 0; + var j = 1; + while (j < nums.Length) + { + if (nums[i] != nums[j] || i == 0 || nums[i] == nums[j] && nums[i - 1] != nums[j]) + { + nums[++i] = nums[j]; + } + ++j; + } + return i + 1; + } +} \ No newline at end of file diff --git a/solution/0082.Remove Duplicates from Sorted List II/Solution.cs b/solution/0082.Remove Duplicates from Sorted List II/Solution.cs new file mode 100644 index 0000000000000..bb6fbe333ac31 --- /dev/null +++ b/solution/0082.Remove Duplicates from Sorted List II/Solution.cs @@ -0,0 +1,43 @@ +public class Solution { + private ListNode newHead; + private ListNode last; + private ListNode candidate; + private int count; + + public ListNode DeleteDuplicates(ListNode head) { + while (head != null) + { + if (candidate == null || candidate.val != head.val) + { + TryAppend(); + candidate = head; + count = 1; + } + else + { + ++count; + } + + head = head.next; + } + TryAppend(); + if (last != null) last.next = null; + return newHead; + } + + private void TryAppend() + { + if (count == 1) + { + if (newHead == null) + { + newHead = last = candidate; + } + else + { + last.next = candidate; + last = last.next; + } + } + } +} \ No newline at end of file diff --git a/solution/0083.Remove Duplicates from Sorted List/Solution.cs b/solution/0083.Remove Duplicates from Sorted List/Solution.cs new file mode 100644 index 0000000000000..5f9e8e23efb1f --- /dev/null +++ b/solution/0083.Remove Duplicates from Sorted List/Solution.cs @@ -0,0 +1,21 @@ +public class Solution { + public ListNode DeleteDuplicates(ListNode head) { + if (head == null) return null; + var last = head; + var current = head.next; + while (current != null) + { + if (current.val != last.val) + { + last.next = current; + last = current; + } + else + { + last.next = null; + } + current = current.next; + } + return head; + } +} \ No newline at end of file diff --git a/solution/0084.Largest Rectangle in Histogram/Solution.cs b/solution/0084.Largest Rectangle in Histogram/Solution.cs new file mode 100644 index 0000000000000..ba7d332efc4a9 --- /dev/null +++ b/solution/0084.Largest Rectangle in Histogram/Solution.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +public class Solution { + public int LargestRectangleArea(int[] height) { + var stack = new Stack(); + var result = 0; + var i = 0; + while (i < height.Length || stack.Any()) + { + if (!stack.Any() || (i < height.Length && height[stack.Peek()] < height[i])) + { + stack.Push(i); + ++i; + } + else + { + var previousIndex = stack.Pop(); + var area = height[previousIndex] * (stack.Any() ? (i - stack.Peek() - 1) : i); + result = Math.Max(result, area); + } + } + + return result; + } +} \ No newline at end of file diff --git a/solution/0085.Maximal Rectangle/Solution.cs b/solution/0085.Maximal Rectangle/Solution.cs new file mode 100644 index 0000000000000..de354ffdc8b71 --- /dev/null +++ b/solution/0085.Maximal Rectangle/Solution.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +public class Solution { + private int MaximalRectangleHistagram(int[] height) { + var stack = new Stack(); + var result = 0; + var i = 0; + while (i < height.Length || stack.Any()) + { + if (!stack.Any() || (i < height.Length && height[stack.Peek()] < height[i])) + { + stack.Push(i); + ++i; + } + else + { + var previousIndex = stack.Pop(); + var area = height[previousIndex] * (stack.Any() ? (i - stack.Peek() - 1) : i); + result = Math.Max(result, area); + } + } + + return result; + } + + public int MaximalRectangle(char[][] matrix) { + var lenI = matrix.Length; + var lenJ = lenI == 0 ? 0 : matrix[0].Length; + var height = new int[lenJ]; + var result = 0; + for (var i = 0; i < lenI; ++i) + { + for (var j = 0; j < lenJ; ++j) + { + if (matrix[i][j] == '1') + { + ++height[j]; + } + else + { + height[j] = 0; + } + } + result = Math.Max(result, MaximalRectangleHistagram(height)); + } + return result; + } +} \ No newline at end of file diff --git a/solution/0087.Scramble String/Solution.cs b/solution/0087.Scramble String/Solution.cs new file mode 100644 index 0000000000000..5b944fdacfcb7 --- /dev/null +++ b/solution/0087.Scramble String/Solution.cs @@ -0,0 +1,35 @@ +public class Solution { + public bool IsScramble(string s1, string s2) { + if (s1.Length != s2.Length) return false; + var length = s1.Length; + if (length == 0) return true; + var f = new bool[length + 1, length, length]; + for (var i = 0; i < length; ++i) + { + for (var j = 0; j < length; ++j) + { + f[1, i, j] = s1[i] == s2[j]; + } + } + for (var i = 2; i <= length; ++i) + { + for (var j = 0; j <= length - i; ++j) + { + for (var k = 0; k <= length - i; ++k) + { + for (var l = 1; l < i; ++l) + { + if (f[l, j, k] && f[i - l, j + l, k + l] + || f[l, j, k + i - l] && f[i - l, j + l, k]) + { + f[i, j, k] = true; + break; + } + } + } + } + } + + return f[length, 0, 0]; + } +} \ No newline at end of file diff --git a/solution/0091.Decode Ways/Solution.cs b/solution/0091.Decode Ways/Solution.cs new file mode 100644 index 0000000000000..200f101678b50 --- /dev/null +++ b/solution/0091.Decode Ways/Solution.cs @@ -0,0 +1,25 @@ +public class Solution { + public int NumDecodings(string s) { + if (s.Length == 0) return 0; + + var f0 = 1; + var f1 = 1; + var f2 = 1; + for (var i = 0; i < s.Length; ++i) + { + f0 = f1; + f1 = f2; + f2 = 0; + var two = i > 0 ? int.Parse(string.Format("{0}{1}", s[i - 1], s[i])) : 0; + if (two >= 10 && two <= 26) + { + f2 += f0; + } + if (s[i] != '0') + { + f2 += f1; + } + } + return f2; + } +} \ No newline at end of file diff --git a/solution/0092.Reverse Linked List II/Solution.cs b/solution/0092.Reverse Linked List II/Solution.cs new file mode 100644 index 0000000000000..783ce47b502fc --- /dev/null +++ b/solution/0092.Reverse Linked List II/Solution.cs @@ -0,0 +1,35 @@ +public class Solution { + public ListNode ReverseBetween(ListNode head, int m, int n) { + ListNode part1Head = null; + ListNode part1Tail = null; + for (var i = 1; i < m; ++i) + { + if (part1Head == null) + { + part1Head = head; + } + part1Tail = head; + head = head.next; + } + if (part1Tail != null) part1Tail.next = null; + ListNode part2Head = null; + ListNode part2Tail = null; + for (var i = m; i <= n; ++i) + { + var next = head.next; + head.next = part2Head; + part2Head = head; + if (part2Tail == null) + { + part2Tail = head; + } + head = next; + } + if (part1Tail != null) + { + part1Tail.next = part2Head; + } + part2Tail.next = head; + return part1Head ?? part2Head; + } +} \ No newline at end of file diff --git a/solution/0093.Restore IP Addresses/Solution.cs b/solution/0093.Restore IP Addresses/Solution.cs new file mode 100644 index 0000000000000..03055bfb145e6 --- /dev/null +++ b/solution/0093.Restore IP Addresses/Solution.cs @@ -0,0 +1,44 @@ +using System.Collections.Generic; +using System.Linq; + +public class Solution { + public IList RestoreIpAddresses(string s) { + if (s.Length > 12) return new List(); + var results = new HashSet(); + for (var i = 0; i < s.Length - 3; ++i) + { + for (var j = i + 1; j < s.Length - 2; ++j) + { + for (var k = j + 1; k < s.Length - 1; ++k) + { + var part1 = Normalize(s.Substring(0, i + 1)); + var part2 = Normalize(s.Substring(i + 1, j - i)); + var part3 = Normalize(s.Substring(j + 1, k - j)); + var part4 = Normalize(s.Substring(k + 1)); + + if (part1 != null && part2 != null && part3 != null && part4 != null) + { + results.Add(string.Format("{0}.{1}.{2}.{3}", part1, part2, part3, part4)); + } + } + } + } + + return results.ToList(); + } + + private string Normalize(string part) + { + if (part == "0") return part; + if (part[0] == '0') return null; + byte temp = 0; + if (byte.TryParse(part, out temp)) + { + return part; + } + else + { + return null; + } + } +} \ No newline at end of file diff --git a/solution/0097.Interleaving String/Solution.cs b/solution/0097.Interleaving String/Solution.cs new file mode 100644 index 0000000000000..b1167ef293ef2 --- /dev/null +++ b/solution/0097.Interleaving String/Solution.cs @@ -0,0 +1,33 @@ +using System; + +public class Solution { + public bool IsInterleave(string s1, string s2, string s3) { + if (s1.Length + s2.Length != s3.Length) return false; + var f = new bool[s3.Length + 1, s1.Length + 1]; + f[0, 0] = true; + for (var i = 1; i <= s3.Length; ++i) + { + var j = Math.Max(0, i - s2.Length); + var k = i - j; + while (j <= s1.Length) + { + if (j > 0 && s3[i - 1] == s1[j - 1] && f[i - 1, j - 1]) + { + f[i, j] = true; + } + else if (k > 0 && s3[i - 1] == s2[k - 1] && f[i - 1, j]) + { + f[i, j] = true; + } + ++j; + --k; + } + } + + for (var i = 0; i <= s1.Length; ++i) + { + if (f[s3.Length, i]) return true; + } + return false; + } +} \ No newline at end of file diff --git a/solution/0098.Validate Binary Search Tree/Solution.cs b/solution/0098.Validate Binary Search Tree/Solution.cs new file mode 100644 index 0000000000000..e5af22a051aa2 --- /dev/null +++ b/solution/0098.Validate Binary Search Tree/Solution.cs @@ -0,0 +1,13 @@ +public class Solution { + public bool IsValidBST(TreeNode root) { + return IsValidBstInternal(root, int.MinValue, int.MaxValue); + } + + private bool IsValidBstInternal(TreeNode root, int min, int max) + { + if (root == null) return true; + if (root.val < min || root.val > max) return false; + return (root.val == int.MinValue ? root.left == null : IsValidBstInternal(root.left, min, root.val - 1)) + && (root.val == int.MaxValue ? root.right == null : IsValidBstInternal(root.right, root.val + 1, max)); + } +} \ No newline at end of file diff --git a/solution/0099.Recover Binary Search Tree/Solution.cs b/solution/0099.Recover Binary Search Tree/Solution.cs new file mode 100644 index 0000000000000..d869c8ade54d0 --- /dev/null +++ b/solution/0099.Recover Binary Search Tree/Solution.cs @@ -0,0 +1,62 @@ +public class Solution { + private TreeNode last, first, second; + + public void RecoverTree(TreeNode root) { + Traverse(root); + var temp = first.val; + first.val = second.val; + second.val = temp; + } + + private void Traverse(TreeNode root) + { + var current = root; + TreeNode temp; + while (current != null) + { + if (current.left == null) + { + Visit(current); + current = current.right; + } + else + { + temp = current.left; + while (temp.right != null && temp.right != current) + { + temp = temp.right; + } + if (temp.right == null) + { + temp.right = current; + current = current.left; + } + else + { + Visit(current); + temp.right = null; + current = current.right; + } + } + } + } + + private void Visit(TreeNode node) + { + if (last != null) + { + if (node.val < last.val) + { + if (first == null) + { + first = last; + } + } + if (first != null && node.val < first.val) + { + second = node; + } + } + last = node; + } +} diff --git a/solution/0121.Best Time to Buy and Sell Stock/Solution.cs b/solution/0121.Best Time to Buy and Sell Stock/Solution.cs new file mode 100644 index 0000000000000..12dfc5f3b0e0e --- /dev/null +++ b/solution/0121.Best Time to Buy and Sell Stock/Solution.cs @@ -0,0 +1,18 @@ +public class Solution { + public int MaxProfit(int[] prices) { + var result = 0; + var minPrice = int.MaxValue; + foreach (var price in prices) + { + if (price > minPrice && result < price - minPrice) + { + result = price - minPrice; + } + if (price < minPrice) + { + minPrice = price; + } + } + return result; + } +} \ No newline at end of file diff --git a/solution/0122.Best Time to Buy and Sell Stock II/Solution.cs b/solution/0122.Best Time to Buy and Sell Stock II/Solution.cs new file mode 100644 index 0000000000000..4f61a6c909d63 --- /dev/null +++ b/solution/0122.Best Time to Buy and Sell Stock II/Solution.cs @@ -0,0 +1,20 @@ +public class Solution { + public int MaxProfit(int[] prices) { + var result = 0; + var i = 0; + while (i + 1 < prices.Length) + { + while (i + 1 < prices.Length && prices[i] >= prices[i + 1]) + { + ++i; + } + result -= prices[i]; + while (i + 1 < prices.Length && prices[i] <= prices[i + 1]) + { + ++i; + } + result += prices[i]; + } + return result; + } +} \ No newline at end of file diff --git a/solution/0123.Best Time to Buy and Sell Stock III/Solution.cs b/solution/0123.Best Time to Buy and Sell Stock III/Solution.cs new file mode 100644 index 0000000000000..6828bf21bfe7d --- /dev/null +++ b/solution/0123.Best Time to Buy and Sell Stock III/Solution.cs @@ -0,0 +1,37 @@ +using System; + +public class Solution { + public int MaxProfit(int[] prices) { + int[] leftProfit = new int[prices.Length]; + int[] rightProfit = new int[prices.Length]; + + // iterate from left to right + var minPrice = int.MaxValue; + var leftMaxProfit = 0; + for (var i = 0; i < prices.Length; ++i) + { + minPrice = Math.Min(minPrice, prices[i]); + leftMaxProfit = Math.Max(leftMaxProfit, prices[i] - minPrice); + leftProfit[i] = leftMaxProfit; + } + + // iterate from right to left + var maxPrice = int.MinValue; + var rightMaxProfit = 0; + for (var i = prices.Length - 1; i >= 0; --i) + { + maxPrice = Math.Max(maxPrice, prices[i]); + rightMaxProfit = Math.Max(rightMaxProfit, maxPrice - prices[i]); + rightProfit[i] = rightMaxProfit; + } + + // merge two profits + var maxProfit = 0; + for (var i = 0; i < prices.Length; ++i) + { + maxProfit = Math.Max(maxProfit, leftProfit[i] + rightProfit[i]); + } + + return maxProfit; + } +} \ No newline at end of file diff --git a/solution/0124.Binary Tree Maximum Path Sum/Solution.cs b/solution/0124.Binary Tree Maximum Path Sum/Solution.cs new file mode 100644 index 0000000000000..fbbf487f545b5 --- /dev/null +++ b/solution/0124.Binary Tree Maximum Path Sum/Solution.cs @@ -0,0 +1,21 @@ +using System; + +public class Solution { + private int _answer = int.MinValue; + public int MaxPathSum(TreeNode root) { + GetMaxSumOfOneSide(root); + return _answer; + } + + private int GetMaxSumOfOneSide(TreeNode root) + { + if (root == null) return 0; + var leftSum = GetMaxSumOfOneSide(root.left); + if (leftSum < 0) leftSum = 0; + var rightSum = GetMaxSumOfOneSide(root.right); + if (rightSum < 0) rightSum = 0; + var all = leftSum + rightSum + root.val; + _answer = Math.Max(_answer, all); + return Math.Max(root.val, root.val + Math.Max(leftSum, rightSum)); + } +} \ No newline at end of file diff --git a/solution/0125.Valid Palindrome/Solution.cs b/solution/0125.Valid Palindrome/Solution.cs new file mode 100644 index 0000000000000..dc2c4e9ad4223 --- /dev/null +++ b/solution/0125.Valid Palindrome/Solution.cs @@ -0,0 +1,14 @@ +using System.Linq; + +public class Solution { + public bool IsPalindrome(string s) { + var chars = s.Where(ch => char.IsLetterOrDigit(ch)).Select(char.ToLower).ToList(); + var i = 0; + var j = chars.Count - 1; + for (; i < j; ++i, --j) + { + if (chars[i] != chars[j]) return false; + } + return true; + } +} \ No newline at end of file diff --git a/solution/0127.Word Ladder/Solution.cs b/solution/0127.Word Ladder/Solution.cs new file mode 100644 index 0000000000000..7ca47c3935654 --- /dev/null +++ b/solution/0127.Word Ladder/Solution.cs @@ -0,0 +1,68 @@ +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +public class Solution { + public int LadderLength(string beginWord, string endWord, IList wordList) { + var words = Enumerable.Repeat(beginWord, 1).Concat(wordList).Select((word, i) => new { Word = word, Index = i }).ToList(); + var endWordIndex = words.Find(w => w.Word == endWord)?.Index; + if (endWordIndex == null) { + return 0; + } + + var paths = new List[words.Count]; + for (var i = 0; i < paths.Length; ++i) + { + paths[i] = new List(); + } + for (var i = 0; i < beginWord.Length; ++i) + { + var hashMap = new Hashtable(); + foreach (var item in words) + { + var newWord = string.Format("{0}_{1}", item.Word.Substring(0, i), item.Word.Substring(i + 1)); + List similars; + if (!hashMap.ContainsKey(newWord)) + { + similars = new List(); + hashMap.Add(newWord, similars); + } + else + { + similars = (List)hashMap[newWord]; + } + foreach (var similar in similars) + { + paths[similar].Add(item.Index); + paths[item.Index].Add(similar); + } + similars.Add(item.Index); + } + } + + var left = words.Count - 1; + var lastRound = new List { 0 }; + var visited = new bool[words.Count]; + visited[0] = true; + for (var result = 2; left > 0; ++result) + { + var thisRound = new List(); + foreach (var index in lastRound) + { + foreach (var next in paths[index]) + { + if (!visited[next]) + { + visited[next] = true; + if (next == endWordIndex) return result; + thisRound.Add(next); + } + } + } + if (thisRound.Count == 0) break; + lastRound = thisRound; + } + + return 0; + } +} \ No newline at end of file diff --git a/solution/0130.Surrounded Regions/Solution.cs b/solution/0130.Surrounded Regions/Solution.cs new file mode 100644 index 0000000000000..9ddb0b2e7798b --- /dev/null +++ b/solution/0130.Surrounded Regions/Solution.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; + +public class Solution { + private static readonly int[,] directions = new int[4, 2] { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 }}; + public void Solve(char[][] board) { + var lenI = board.Length; + var lenJ = lenI == 0 ? 0 : board[0].Length; + + for (var i = 0; i < lenI; ++i) + { + for (var j = 0; j < lenJ; ++j) + { + if (board[i][j] == 'O') + { + var marked = new List>(); + marked.Add(Tuple.Create(i, j)); + board[i][j] = 'M'; + bool escaped = false; + for (var m = 0; m < marked.Count; ++m) + { + for (var k = 0; k < 4; ++k) + { + var newI = marked[m].Item1 + directions[k, 0]; + var newJ = marked[m].Item2 + directions[k, 1]; + if (newI < 0 || newI >= lenI || newJ < 0 || newJ >= lenJ) + { + escaped = true; + } + else if (board[newI][newJ] == 'O') + { + board[newI][newJ] = 'M'; + marked.Add(Tuple.Create(newI, newJ)); + } + } + } + + if (!escaped) + { + foreach (var item in marked) + { + board[item.Item1][item.Item2] = 'X'; + } + } + } + } + } + + for (var i = 0; i < lenI; ++i) + { + for (var j = 0; j < lenJ; ++j) + { + if (board[i][j] == 'M') + { + board[i][j] = 'O'; + } + } + } + } +} \ No newline at end of file diff --git a/solution/0131.Palindrome Partitioning/Solution.cs b/solution/0131.Palindrome Partitioning/Solution.cs new file mode 100644 index 0000000000000..fe3e28325c427 --- /dev/null +++ b/solution/0131.Palindrome Partitioning/Solution.cs @@ -0,0 +1,85 @@ +using System.Collections.Generic; +using System.Linq; + +public class Solution { + public IList> Partition(string s) { + if (s.Length == 0) return new List>(); + + var paths = new List[s.Length]; + for (var i = 0; i < s.Length; ++i) + { + int j, k; + for (j = i, k = i + 1; j >= 0 && k < s.Length; --j, ++k) + { + if (s[j] == s[k]) + { + if (paths[k] == null) + { + paths[k] = new List(); + } + paths[k].Add(j - 1); + } + else + { + break; + } + } + for (j = i, k = i; j >= 0 && k < s.Length; --j, ++k) + { + if (s[j] == s[k]) + { + if (paths[k] == null) + { + paths[k] = new List(); + } + paths[k].Add(j - 1); + } + else + { + break; + } + } + } + + var prevs = new List[s.Length]; + for (var i = 0; i < s.Length; ++i) + { + if (paths[i] != null) + { + foreach (var path in paths[i]) + { + if (path < 0 || prevs[path] != null) + { + if (prevs[i] == null) + { + prevs[i] = new List(); + } + prevs[i].Add(path); + } + } + } + } + + var results = new List>(); + var temp = new List(); + GenerateResults(prevs, s, s.Length - 1, temp, results); + return results; + } + + private void GenerateResults(List[] prevs, string s, int i, IList temp, IList> results) + { + if (i < 0) + { + results.Add(temp.Reverse().ToList()); + } + else + { + foreach (var prev in prevs[i]) + { + temp.Add(s.Substring(prev + 1, i - prev)); + GenerateResults(prevs, s, prev, temp, results); + temp.RemoveAt(temp.Count - 1); + } + } + } +} \ No newline at end of file diff --git a/solution/0132.Palindrome Partitioning II/Solution.cs b/solution/0132.Palindrome Partitioning II/Solution.cs new file mode 100644 index 0000000000000..c1d1f3af186b8 --- /dev/null +++ b/solution/0132.Palindrome Partitioning II/Solution.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; + +public class Solution { + public int MinCut(string s) { + if (s.Length == 0) return 0; + + var paths = new List[s.Length]; + for (var i = 0; i < s.Length; ++i) + { + int j, k; + for (j = i, k = i + 1; j >= 0 && k < s.Length; --j, ++k) + { + if (s[j] == s[k]) + { + if (paths[k] == null) + { + paths[k] = new List(); + } + paths[k].Add(j - 1); + } + else + { + break; + } + } + for (j = i, k = i; j >= 0 && k < s.Length; --j, ++k) + { + if (s[j] == s[k]) + { + if (paths[k] == null) + { + paths[k] = new List(); + } + paths[k].Add(j - 1); + } + else + { + break; + } + } + } + + var partCount = new int[s.Length]; + for (var i = 0; i < s.Length; ++i) + { + partCount[i] = int.MaxValue; + if (paths[i] != null) + { + foreach (var path in paths[i]) + { + if (path < 0) + { + partCount[i] = 0; + break; + } + else + { + partCount[i] = Math.Min(partCount[i], partCount[path]); + } + } + } + ++partCount[i]; + } + return partCount[s.Length - 1] - 1; + } +} \ No newline at end of file diff --git a/solution/0133.Clone Graph/Solution.cs b/solution/0133.Clone Graph/Solution.cs new file mode 100644 index 0000000000000..9abef5a6044c3 --- /dev/null +++ b/solution/0133.Clone Graph/Solution.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; + +public class Solution { + public Node CloneGraph(Node node) { + if (node == null) return null; + var dict = new Dictionary(); + var queue = new Queue(); + queue.Enqueue(CloneVal(node)); + dict.Add(node.val, queue.Peek()); + while (queue.Count > 0) + { + var current = queue.Dequeue(); + var newNeighbors = new List(current.neighbors.Count); + foreach (var oldNeighbor in current.neighbors) + { + Node newNeighbor; + if (!dict.TryGetValue(oldNeighbor.val, out newNeighbor)) + { + newNeighbor = CloneVal(oldNeighbor); + queue.Enqueue(newNeighbor); + dict.Add(newNeighbor.val, newNeighbor); + } + newNeighbors.Add(newNeighbor); + } + current.neighbors = newNeighbors; + } + return dict[node.val]; + } + + private Node CloneVal(Node node) + { + return new Node(node.val, new List(node.neighbors)); + } +} \ No newline at end of file diff --git a/solution/0134.Gas Station/Solution.cs b/solution/0134.Gas Station/Solution.cs new file mode 100644 index 0000000000000..94621d702a0fa --- /dev/null +++ b/solution/0134.Gas Station/Solution.cs @@ -0,0 +1,30 @@ +public class Solution { + public int CanCompleteCircuit(int[] gas, int[] cost) { + if (gas.Length == 0) return -1; + var startIndex = 0; + var i = 0; + var gasLeft = 0; + while (true) + { + gasLeft += gas[i] - cost[i]; + ++i; + if (i >= gas.Length) i = 0; + if (gasLeft < 0) + { + if (startIndex >= i) + { + return -1; + } + startIndex = i; + gasLeft = 0; + } + else + { + if (startIndex == i) + { + return startIndex; + } + } + } + } +} \ No newline at end of file diff --git a/solution/0135.Candy/Solution.cs b/solution/0135.Candy/Solution.cs new file mode 100644 index 0000000000000..811b114f6d9d0 --- /dev/null +++ b/solution/0135.Candy/Solution.cs @@ -0,0 +1,40 @@ +public class Solution { + public int Candy(int[] ratings) { + if (ratings.Length == 0) return 0; + var result = 0; + var previousRating = ratings[0]; + var previousCandy = 0; + var downCount = 0; + int? downCountThreshold = null; + foreach (var rating in ratings) + { + if (rating == previousRating) + { + result += 1; + previousCandy = 1; + downCount = 1; + downCountThreshold = null; + } + else if (rating > previousRating) + { + ++previousCandy; + result += previousCandy; + downCount = 1; + downCountThreshold = null; + } + else + { + if (downCountThreshold == null) + { + downCountThreshold = previousCandy - 1; + } + previousCandy = 1; + result += downCount + (downCount > downCountThreshold.Value ? 1 : 0); + ++downCount; + } + previousRating = rating; + //System.Console.WriteLine("{0} {1}", previousCandy, result); + } + return result; + } +} \ No newline at end of file diff --git a/solution/0138.Copy List with Random Pointer/Solution.cs b/solution/0138.Copy List with Random Pointer/Solution.cs new file mode 100644 index 0000000000000..8a689696f5053 --- /dev/null +++ b/solution/0138.Copy List with Random Pointer/Solution.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; + +public class Solution { + public Node CopyRandomList(Node head) { + if (head == null) { + return null; + } + + var map = new Dictionary(); + var current = head; + while (current != null) { + var newCurrent = new Node(current.val); + map.Add(current, newCurrent); + current = current.next; + } + + foreach (var entry in map) { + var oldNode = entry.Key; + var newNode = entry.Value; + if (oldNode.next != null) { + newNode.next = map[oldNode.next]; + } + if (oldNode.random != null) { + newNode.random = map[oldNode.random]; + } + } + + return map[head]; + } +} \ No newline at end of file diff --git a/solution/0139.Word Break/Solution.cs b/solution/0139.Word Break/Solution.cs new file mode 100644 index 0000000000000..b9ec5f963f1f8 --- /dev/null +++ b/solution/0139.Word Break/Solution.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using System.Linq; + +public class Solution { + public bool WordBreak(string s, IList wordDict) { + var f = new bool[s.Length + 1]; + f[0] = true; + var wordDictGroup = wordDict.GroupBy(word => word.Length); + for (var i = 1; i <= s.Length; ++i) + { + foreach (var wordGroup in wordDictGroup) + { + var wordLength = wordGroup.Key; + if (i >= wordLength && f[i - wordLength]) + { + foreach (var word in wordGroup) + { + if (s.Substring(i - wordLength, wordLength) == word) + { + f[i] = true; + break; + } + } + } + } + } + return f[s.Length]; + } +} \ No newline at end of file diff --git a/solution/0140.Word Break II/Solution.cs b/solution/0140.Word Break II/Solution.cs new file mode 100644 index 0000000000000..b6f56226e5e10 --- /dev/null +++ b/solution/0140.Word Break II/Solution.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +class Node +{ + public int Index1 { get; set; } + public int Index2 { get; set; } +} + +public class Solution { + public IList WordBreak(string s, IList wordDict) { + var paths = new List>[s.Length + 1]; + paths[s.Length] = new List> { Tuple.Create(-1, (string)null) }; + var wordDictGroup = wordDict.GroupBy(word => word.Length); + for (var i = s.Length - 1; i >= 0; --i) + { + paths[i] = new List>(); + foreach (var wordGroup in wordDictGroup) + { + var wordLength = wordGroup.Key; + if (i + wordLength <= s.Length && paths[i + wordLength].Count > 0) + { + foreach (var word in wordGroup) + { + if (s.Substring(i, wordLength) == word) + { + paths[i].Add(Tuple.Create(i + wordLength, word)); + } + } + } + } + } + + return GenerateResults(paths); + } + + private IList GenerateResults(List>[] paths) + { + var results = new List(); + var sb = new StringBuilder(); + var stack = new Stack(); + stack.Push(new Node()); + while (stack.Count > 0) + { + var node = stack.Peek(); + if (node.Index1 == paths.Length - 1 || node.Index2 == paths[node.Index1].Count) + { + if (node.Index1 == paths.Length - 1) + { + results.Add(sb.ToString()); + } + stack.Pop(); + if (stack.Count > 0) + { + var parent = stack.Peek(); + var length = paths[parent.Index1][parent.Index2 - 1].Item2.Length; + if (length < sb.Length) ++length; + sb.Remove(sb.Length - length, length); + } + } + else + { + var newNode = new Node { Index1 = paths[node.Index1][node.Index2].Item1, Index2 = 0 }; + if (sb.Length != 0) + { + sb.Append(' '); + } + sb.Append(paths[node.Index1][node.Index2].Item2); + stack.Push(newNode); + ++node.Index2; + } + } + return results; + } +} \ No newline at end of file diff --git a/solution/0143.Reorder List/Solution.cs b/solution/0143.Reorder List/Solution.cs new file mode 100644 index 0000000000000..eb6c9589faf75 --- /dev/null +++ b/solution/0143.Reorder List/Solution.cs @@ -0,0 +1,55 @@ +public class Solution { + public void ReorderList(ListNode head) { + var mid = FindMiddleNode(head); + if (mid == null || mid.next == null) return; + var head2 = mid.next; + mid.next = null; + head2 = ReverseList(head2); + MergeList(head, head2); + } + + private ListNode FindMiddleNode(ListNode head) + { + var last = head; + var mid = head; + while (last != null) + { + last = last.next; + if (last != null) + { + last = last.next; + mid = mid.next; + } + } + return mid; + } + + private ListNode ReverseList(ListNode head) + { + var current = head; + head = null; + while (current != null) + { + var next = current.next; + current.next = head; + head = current; + current = next; + } + return head; + } + + private void MergeList(ListNode head1, ListNode head2) + { + var p1 = head1; + var p2 = head2; + while (p2 != null) + { + var p1Next = p1.next; + var p2Next = p2.next; + p1.next = p2; + p2.next = p1Next; + p1 = p1Next; + p2 = p2Next; + } + } +} \ No newline at end of file diff --git a/solution/0146.Lru Cache/Solution.cs b/solution/0146.Lru Cache/Solution.cs new file mode 100644 index 0000000000000..1b25c661464c9 --- /dev/null +++ b/solution/0146.Lru Cache/Solution.cs @@ -0,0 +1,111 @@ +// https://leetcode.com/problems/lru-cache/ + +using System.Collections.Generic; + +public class LRUCache +{ + class Node + { + public Node Prev; + public Node Next; + public int Key; + public int Value; + } + + private Node _head; + private Node _tail; + private Dictionary keyMap; + private readonly int _capacity; + + public LRUCache(int capacity) + { + _capacity = capacity; + keyMap = new Dictionary(); + } + + public int Get(int key) + { + Node node; + if (keyMap.TryGetValue(key, out node)) + { + MoveToHead(node); + return node.Value; + } + return -1; + } + + public void Put(int key, int value) + { + Node node; + if (keyMap.TryGetValue(key, out node)) + { + MoveToHead(node); + node.Value = value; + } + else + { + if (keyMap.Count == _capacity) + { + if (_capacity > 0) + { + keyMap.Remove(_tail.Key); + RemoveTail(); + } + else + { + return; + } + } + node = new Node() { Key = key, Value = value }; + keyMap.Add(key, node); + MoveToHead(node); + } + } + + private void MoveToHead(Node node) + { + if (_head != node) + { + if (_head == null) + { + _head = node; + _tail = node; + } + else + { + if (_tail == node) + { + _tail = node.Prev; + } + if (node.Next != null) + { + node.Next.Prev = node.Prev; + } + if (node.Prev != null) + { + node.Prev.Next = node.Next; + } + node.Next = _head; + _head.Prev = node; + _head = node; + } + } + } + + private void RemoveTail() + { + if (_tail != null) + { + if (_tail.Prev == null) + { + _head = null; + _tail = null; + } + else + { + _tail = _tail.Prev; + _tail.Next = null; + } + } + } +} \ No newline at end of file diff --git a/solution/0148.Sort List/Solution.cs b/solution/0148.Sort List/Solution.cs new file mode 100644 index 0000000000000..80df3820106af --- /dev/null +++ b/solution/0148.Sort List/Solution.cs @@ -0,0 +1,50 @@ +public class Solution { + public ListNode SortList(ListNode head) { + if (head == null || head.next == null) + { + return head; + } + + ListNode p1 = null; + var p2 = head; + while (p2 != null) + { + p2 = p2.next; + if (p2 != null) + { + p2 = p2.next; + p1 = p1 == null ? head : p1.next; + } + } + + p2 = p1.next; + p1.next = null; + p1 = head; + p1 = SortList(p1); + p2 = SortList(p2); + ListNode newHead = null; + ListNode newTail = null; + while (p1 != null || p2 != null) + { + if (p1 == null || (p2 != null && p1.val > p2.val)) + { + var temp = p1; + p1 = p2; + p2 = temp; + } + var next = p1; + p1 = p1.next; + next.next = null; + if (newTail == null) + { + newHead = newTail = next; + } + else + { + newTail.next = next; + newTail = next; + } + } + return newHead; + } +} \ No newline at end of file diff --git a/solution/0149.Max Points on a Line/Solution.cs b/solution/0149.Max Points on a Line/Solution.cs new file mode 100644 index 0000000000000..15d440fd38d1f --- /dev/null +++ b/solution/0149.Max Points on a Line/Solution.cs @@ -0,0 +1,101 @@ +// https://leetcode.com/problems/max-points-on-a-line/ + +using System.Collections.Generic; + +public class Solution +{ + class Slope { + private int _x; + private int _y; + + public Slope(int x, int y) { + if (x == 0 && y == 0) { + throw new ArgumentException("Invalid slope."); + } + if (x == 0) { + _x = 0; + _y = 1; + return; + } + if (y == 0) { + _x = 1; + _y = 0; + return; + } + + bool negative = x < 0 && y > 0 || x > 0 && y < 0; + x = Math.Abs(x); + y = Math.Abs(y); + int tx = x; + int ty = y; + int tz = tx % ty; + while (tz > 0) { + tx = ty; + ty = tz; + tz = tx % ty; + } + + _x = x / ty; + _y = (negative ? -1 : 1) * (y / ty); + } + + public override bool Equals(Object obj) + { + if (obj == null || !(obj is Slope)) { + return false; + } else { + return _x == ((Slope) obj)._x && _y == ((Slope) obj)._y; + } + } + + public override int GetHashCode() + { + return _x.GetHashCode() ^ _y.GetHashCode(); + } + } + + public int MaxPoints(int[][] points) + { + var answer = 0; + for (var i = 0; i < points.Length; ++i) + { + var slopes = new Dictionary(); + var samePoint = 0; + var max = 0; + for (var j = i + 1; j < points.Length; ++j) + { + if (points[i][0] == points[j][0] && points[i][1] == points[j][1]) + { + ++samePoint; + } + else + { + var slope = new Slope(points[j][0] - points[i][0], points[j][1] - points[i][1]); + if (slopes.ContainsKey(slope)) + { + ++slopes[slope]; + if (max < slopes[slope]) + { + max = slopes[slope]; + } + } + else + { + slopes[slope] = 1; + if (max < 1) + { + max = 1; + } + } + } + } + + if (1 + samePoint + max > answer) + { + answer = 1 + samePoint + max; + } + } + + return answer; + } +} \ No newline at end of file diff --git a/solution/0150.Evaluate Reverse Polish Notation/Solution.cs b/solution/0150.Evaluate Reverse Polish Notation/Solution.cs new file mode 100644 index 0000000000000..242ee15e87665 --- /dev/null +++ b/solution/0150.Evaluate Reverse Polish Notation/Solution.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; + +public class Solution { + public int EvalRPN(string[] tokens) { + var stack = new Stack(); + foreach (var token in tokens) + { + switch (token) + { + case "+": + stack.Push(stack.Pop() + stack.Pop()); + break; + case "-": + stack.Push(-stack.Pop() + stack.Pop()); + break; + case "*": + stack.Push(stack.Pop() * stack.Pop()); + break; + case "/": + var right = stack.Pop(); + stack.Push(stack.Pop() / right); + break; + default: + stack.Push(int.Parse(token)); + break; + } + } + return stack.Pop(); + } +} \ No newline at end of file diff --git a/solution/0151.Reverse Words in a String/Solution.cs b/solution/0151.Reverse Words in a String/Solution.cs new file mode 100644 index 0000000000000..de9f03ae9afdf --- /dev/null +++ b/solution/0151.Reverse Words in a String/Solution.cs @@ -0,0 +1,41 @@ +using System.Text; +using System.Collections.Generic; +using System.Linq; + +public class Solution { + public string ReverseWords(string s) { + var sb = new StringBuilder(); + var wordList = new List(); + foreach (var ch in s) + { + if (char.IsWhiteSpace(ch)) + { + if (sb.Length > 0) + { + wordList.Add(sb.ToString()); + sb.Clear(); + } + } + else + { + sb.Append(ch); + } + } + if (sb.Length > 0) + { + wordList.Add(sb.ToString()); + sb.Clear(); + } + + foreach (var word in ((IEnumerable)wordList).Reverse()) + { + if (sb.Length > 0) + { + sb.Append(' '); + } + sb.Append(word); + } + + return sb.ToString(); + } +} \ No newline at end of file diff --git a/solution/0152.Maximum Product Subarray/Solution.cs b/solution/0152.Maximum Product Subarray/Solution.cs new file mode 100644 index 0000000000000..86f921c13ff4f --- /dev/null +++ b/solution/0152.Maximum Product Subarray/Solution.cs @@ -0,0 +1,18 @@ +using System; + +public class Solution { + public int MaxProduct(int[] nums) { + var prevMin = 1; + var prevMax = 1; + var result = int.MinValue; + for (var i = 0; i < nums.Length; ++i) + { + var max = Math.Max(nums[i], Math.Max(nums[i] * prevMin, nums[i] * prevMax)); + var min = Math.Min(nums[i], Math.Min(nums[i] * prevMin, nums[i] * prevMax)); + result = Math.Max(result, max); + prevMax = max; + prevMin = min; + } + return result; + } +} \ No newline at end of file diff --git a/solution/0155.Min Stack/Solution.cs b/solution/0155.Min Stack/Solution.cs new file mode 100644 index 0000000000000..fad321664768d --- /dev/null +++ b/solution/0155.Min Stack/Solution.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; + +public class MinStack { + private Stack _stack = new Stack(); + private Stack _minStack = new Stack(); + + public void Push(int x) { + _stack.Push(x); + if (GetMin() >= x) _minStack.Push(x); + } + + public void Pop() { + var x = _stack.Pop(); + if (GetMin() == x) _minStack.Pop(); + } + + public int Top() { + return _stack.Peek(); + } + + public int GetMin() { + if (_minStack.Count == 0) return int.MaxValue; + return _minStack.Peek(); + } +} \ No newline at end of file diff --git a/solution/0164.Maximum Gap/Solution.cs b/solution/0164.Maximum Gap/Solution.cs new file mode 100644 index 0000000000000..8f809f9c60baf --- /dev/null +++ b/solution/0164.Maximum Gap/Solution.cs @@ -0,0 +1,39 @@ +using System; +using System.Linq; + +public class Solution { + public int MaximumGap(int[] nums) { + if (nums.Length < 2) return 0; + var max = nums.Max(); + var min = nums.Min(); + var bucketSize = Math.Max(1, (max - min) / (nums.Length - 1)); + var buckets = new Tuple[(max - min) / bucketSize + 1]; + foreach (var num in nums) + { + var index = (num - min) / bucketSize; + if (buckets[index] == null) + { + buckets[index] = Tuple.Create(num, num); + } + else + { + buckets[index] = Tuple.Create(Math.Min(buckets[index].Item1, num), Math.Max(buckets[index].Item2, num)); + } + } + + var result = 0; + Tuple lastBucket = null; + for (var i = 0; i < buckets.Length; ++i) + { + if (buckets[i] != null) + { + if (lastBucket != null) + { + result = Math.Max(result, buckets[i].Item1 - lastBucket.Item2); + } + lastBucket = buckets[i]; + } + } + return result; + } +} \ No newline at end of file diff --git a/solution/0165.Compare Version Numbers/Solution.cs b/solution/0165.Compare Version Numbers/Solution.cs new file mode 100644 index 0000000000000..d097238a6e9ae --- /dev/null +++ b/solution/0165.Compare Version Numbers/Solution.cs @@ -0,0 +1,31 @@ +using System; +using System.Linq; +using System.Collections.Generic; + +public class Solution { + public int CompareVersion(string version1, string version2) { + var parts1 = version1.Split('.').Select(int.Parse).ToList(); + var parts2 = version2.Split('.').Select(int.Parse).ToList(); + var minLen = Math.Min(parts1.Count, parts2.Count); + for (var i = 0; i < minLen; ++i) + { + if (parts1[i] < parts2[i]) + { + return -1; + } + else if (parts1[i] > parts2[i]) + { + return 1; + } + } + if (parts1.Count > parts2.Count && parts1.Skip(minLen).Any(v => v != 0)) + { + return 1; + } + if (parts2.Count > parts1.Count && parts2.Skip(minLen).Any(v => v != 0)) + { + return -1; + } + return 0; + } +} \ No newline at end of file diff --git a/solution/0166.Fraction to Recurring Decimal/Solution.cs b/solution/0166.Fraction to Recurring Decimal/Solution.cs new file mode 100644 index 0000000000000..b8cfcf8ea12f0 --- /dev/null +++ b/solution/0166.Fraction to Recurring Decimal/Solution.cs @@ -0,0 +1,57 @@ +// https://leetcode.com/problems/fraction-to-recurring-decimal/ + +using System.Collections.Generic; +using System.Text; + +public partial class Solution +{ + public string FractionToDecimal(int numerator, int denominator) + { + var n = (long)numerator; + var d = (long)denominator; + var sb = new StringBuilder(); + if (n < 0) + { + n = -n; + if (d < 0) + { + d = -d; + } + else + { + sb.Append('-'); + } + } + else if (n > 0 && d < 0) + { + d = -d; + sb.Append('-'); + } + + sb.Append(n / d); + n = n % d; + if (n != 0) + { + sb.Append('.'); + var dict = new Dictionary(); + while (n != 0) + { + int index; + if (dict.TryGetValue(n, out index)) + { + sb.Insert(index, '('); + sb.Append(')'); + break; + } + else + { + dict.Add(n, sb.Length); + n *= 10; + sb.Append(n / d); + n %= d; + } + } + } + return sb.ToString(); + } +} \ No newline at end of file diff --git a/solution/0168.Excel Sheet Column Title/Solution.cs b/solution/0168.Excel Sheet Column Title/Solution.cs new file mode 100644 index 0000000000000..892ccc0b0b1d0 --- /dev/null +++ b/solution/0168.Excel Sheet Column Title/Solution.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using System.Linq; +using System.Text; + +public class Solution { + public string ConvertToTitle(int n) { + var list = new List(); + while (n > 0) + { + var x = n % 26; + if (x == 0) x = 26; + list.Add((char)('A' + x - 1)); + n = (n - x) / 26; + } + var sb = new StringBuilder(); + for (var i = list.Count - 1; i >= 0; --i) + { + sb.Append(list[i]); + } + return sb.ToString(); + } +} \ No newline at end of file diff --git a/solution/0169.Majority Element/Solution.cs b/solution/0169.Majority Element/Solution.cs new file mode 100644 index 0000000000000..59948bdce1888 --- /dev/null +++ b/solution/0169.Majority Element/Solution.cs @@ -0,0 +1,30 @@ +public class Solution { + public int MajorityElement(int[] nums) { + return Sort(nums, 0, nums.Length - 1); + } + + private int Sort(int[] nums, int left, int right) + { + if (left == right) return nums[left]; + var targetIndex = nums.Length / 2; + var mid = nums[(left + right) / 2]; + var i = left; + var j = right; + while (i <= j) + { + while (nums[i] < mid) ++i; + while (nums[j] > mid) --j; + if (i <= j) + { + var temp = nums[i]; + nums[i] = nums[j]; + nums[j] = temp; + ++i; + --j; + } + } + if (targetIndex <= j) return Sort(nums, left, j); + if (targetIndex >= i) return Sort(nums, i, right); + return mid; + } +} \ No newline at end of file diff --git a/solution/0174.Dungeon Game/Solution.cs b/solution/0174.Dungeon Game/Solution.cs new file mode 100644 index 0000000000000..ca03cbb38b76d --- /dev/null +++ b/solution/0174.Dungeon Game/Solution.cs @@ -0,0 +1,22 @@ +using System; + +public class Solution { + public int CalculateMinimumHP(int[][] dungeon) { + var len1 = dungeon.Length; + var len2 = len1 == 0 ? 0 : dungeon[0].Length; + var f = new long[len1, len2]; + for (var i = len1 - 1; i >= 0; --i) + { + for (var j = len2 - 1; j >= 0; --j) + { + var down = (i == len1 - 1) ? long.MaxValue : f[i + 1, j]; + var right = (j == len2 - 1) ? long.MaxValue : f[i, j + 1]; + f[i, j] = Math.Min(down, right); + if (f[i, j] == long.MaxValue) f[i, j] = 1; + f[i, j] -= dungeon[i][j]; + if (f[i, j] < 1) f[i, j] = 1; + } + } + return (int) f[0, 0]; + } +} \ No newline at end of file diff --git a/solution/0179.Largest Number/Solution.cs b/solution/0179.Largest Number/Solution.cs new file mode 100644 index 0000000000000..2b5248ed76e28 --- /dev/null +++ b/solution/0179.Largest Number/Solution.cs @@ -0,0 +1,54 @@ +using System; +using System.Globalization; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +public class Comparer: IComparer +{ + public int Compare(string left, string right) + { + return Compare(left, right, 0, 0); + } + + private int Compare(string left, string right, int lBegin, int rBegin) + { + var len = Math.Min(left.Length - lBegin, right.Length - rBegin); + for (var i = 0; i < len; ++i) + { + if (left[lBegin + i] != right[rBegin + i]) + { + return left[lBegin + i] < right[rBegin + i] ? -1 : 1; + } + } + + if (left.Length - lBegin == right.Length - rBegin) + { + return 0; + } + if (left.Length - lBegin > right.Length - rBegin) + { + return Compare(left, right, lBegin + len, rBegin); + } + else + { + return Compare(left, right, lBegin, rBegin + len); + } + } +} + +public class Solution { + public string LargestNumber(int[] nums) { + var sb = new StringBuilder(); + var strs = nums.Select(n => n.ToString(CultureInfo.InvariantCulture)).OrderByDescending(s => s, new Comparer()); + + var nonZeroOccurred = false; + foreach (var str in strs) + { + if (!nonZeroOccurred && str == "0") continue; + sb.Append(str); + nonZeroOccurred = true; + } + return sb.Length == 0 ? "0" : sb.ToString(); + } +} \ No newline at end of file diff --git a/solution/0187.Repeated DNA Sequences/Solution.cs b/solution/0187.Repeated DNA Sequences/Solution.cs new file mode 100644 index 0000000000000..a25a95f770cb8 --- /dev/null +++ b/solution/0187.Repeated DNA Sequences/Solution.cs @@ -0,0 +1,63 @@ +using System.Collections.Generic; + +public class Solution { + public IList FindRepeatedDnaSequences(string s) { + var once = new HashSet(); + var moreThanOnce = new HashSet(); + int bits = 0; + for (var i = 0; i < s.Length; ++i) + { + bits <<= 2; + switch (s[i]) + { + case 'A': + break; + case 'C': + bits |= 1; + break; + case 'G': + bits |= 2; + break; + case 'T': + bits |= 3; + break; + } + if (i >= 10) + { + bits &= 0xFFFFF; + } + if (i >= 9 && !once.Add(bits)) + { + moreThanOnce.Add(bits); + } + } + + var results = new List(); + foreach (var item in moreThanOnce) + { + var itemCopy = item; + var charArray = new char[10]; + for (var i = 9; i >= 0; --i) + { + switch (itemCopy & 3) + { + case 0: + charArray[i] = 'A'; + break; + case 1: + charArray[i] = 'C'; + break; + case 2: + charArray[i] = 'G'; + break; + case 3: + charArray[i] = 'T'; + break; + } + itemCopy >>= 2; + } + results.Add(new string(charArray)); + } + return results; + } +} \ No newline at end of file diff --git a/solution/0188.Best Time to Buy and Sell Stock IV/Solution.cs b/solution/0188.Best Time to Buy and Sell Stock IV/Solution.cs new file mode 100644 index 0000000000000..8c32573c11039 --- /dev/null +++ b/solution/0188.Best Time to Buy and Sell Stock IV/Solution.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +public class Comparer : IComparer>> +{ + public int Compare(LinkedListNode> left, LinkedListNode> right) + { + var result = left.Value.Item1.CompareTo(right.Value.Item1); + if (result == 0 && left != right) + { + return left.Value.Item2.CompareTo(right.Value.Item2); + } + return result; + } +} + +public class Solution { + private SortedSet>> heap = new SortedSet>>(new Comparer()); + private LinkedList> list = new LinkedList>(); + + private int lable = 0; + private Tuple CreateNodeValue(int value) + { + return Tuple.Create(value, lable++); + } + + public int MaxProfitStupid(int k, int[] prices) + { + var f = new int[prices.Length + 1, k + 1]; + for (var i = 2; i <= prices.Length; ++i) + { + for (var kk = 1; kk <= k; ++kk) + { + for (var j = 0; j + 1 < i; ++j) + { + f[i, kk] = Math.Max(f[i, kk], Math.Max(Math.Max(f[i, kk - 1], f[i - 1, kk]), f[j, kk - 1] + prices[i - 1] - prices[j])); + } + } + } + return f[prices.Length, k]; + } + + public int MaxProfit(int k, int[] prices) { + var result = 0; + var i = 0; + var profitCount = 0; + var tempList = new List>(); + while (i + 1 < prices.Length) + { + var highIndex = i; + while (i + 1 < prices.Length && prices[i] >= prices[i + 1]) + { + ++i; + } + var lowIndex = i; + while (i + 1 < prices.Length && prices[i] <= prices[i + 1]) + { + ++i; + } + var highIndex2 = i; + + if (highIndex != lowIndex) + { + tempList.Add(Tuple.Create(prices[highIndex] - prices[lowIndex], false)); + } + if (lowIndex != highIndex2) + { + tempList.Add(Tuple.Create(prices[highIndex2] - prices[lowIndex], true)); + result += prices[highIndex2] - prices[lowIndex]; + ++profitCount; + } + } + + // Trim gaps + if (tempList.Any() && tempList.First().Item2 == false) + { + tempList.RemoveAt(0); + } + if (tempList.Any() && tempList.Last().Item2 == false) + { + tempList.RemoveAt(tempList.Count - 1); + } + + foreach (var temp in tempList) + { + var node = list.AddLast(CreateNodeValue(temp.Item1)); + heap.Add(node); + } + //Console.WriteLine("profitCount: {0}. tempList size: {1}. Heap size: {2}.", profitCount, tempList.Count, heap.Sum(item =>item.Value.Count)); + + for (var j = 0; j < profitCount - k; ++j) + { + var node = heap.Min; + result -= node.Value.Item1; + //Console.WriteLine(node.Value); + var previous = node.Previous; + var next = node.Next; + var newValue = (previous == null ? 0 : previous.Value.Item1) + (next == null ? 0 : next.Value.Item1) - node.Value.Item1; + if (previous != null) + { + heap.Remove(previous); + list.Remove(previous); + } + if (next != null) + { + heap.Remove(next); + list.Remove(next); + } + if (previous != null && next != null) + { + var newNode = list.AddBefore(node, CreateNodeValue(newValue)); + heap.Add(newNode); + } + heap.Remove(node); + list.Remove(node); + } + + return result; + } +} \ No newline at end of file diff --git a/solution/0189.Rotate Array/Solution.cs b/solution/0189.Rotate Array/Solution.cs new file mode 100644 index 0000000000000..65b98661e3245 --- /dev/null +++ b/solution/0189.Rotate Array/Solution.cs @@ -0,0 +1,52 @@ +using System; + +public class Solution { + public void Rotate(int[] nums, int k) { + if (nums.Length == 0 || k % nums.Length == 0) return; + k = k % nums.Length; + Algo2(nums, k); + } + + private void Algo1(int[] nums, int k) + { + var copy = new int[nums.Length]; + Array.Copy(nums, copy, nums.Length); + var j = nums.Length - k; + for (var i = 0; i < nums.Length; ++i) + { + if (j == nums.Length) j = 0; + nums[i] = copy[j]; + ++j; + } + } + + private void Algo2(int[] nums, int k) + { + var gcd = Gcd(nums.Length, k); + var count = nums.Length / gcd; + for (var i = 0; i < gcd; ++i) + { + var p = i; + var first = nums[p]; + for (var j = 0; j + 1 < count; ++j) + { + var q = p - k; + if (q < 0) q += nums.Length; + nums[p] = nums[q]; + p = q; + } + nums[i + k] = first; + } + } + + private int Gcd(int m, int n) + { + while (n > 0) + { + var x = m % n; + m = n; + n = x; + } + return m; + } +} \ No newline at end of file diff --git a/solution/0200.Number of Islands/Solution.cs b/solution/0200.Number of Islands/Solution.cs new file mode 100644 index 0000000000000..c6ecd934cc379 --- /dev/null +++ b/solution/0200.Number of Islands/Solution.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +public class Solution { + public int NumIslands(char[][] grid) + { + var queue = new Queue>(); + var lenI = grid.Length; + var lenJ = lenI == 0 ? 0 : grid[0].Length; + var paths = new int[,] { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } }; + var result = 0; + for (var i = 0; i < lenI; ++i) + { + for (var j = 0; j < lenJ; ++j) + { + if (grid[i][j] == '1') + { + ++result; + grid[i][j] = '0'; + queue.Enqueue(Tuple.Create(i, j)); + while (queue.Any()) + { + var position = queue.Dequeue(); + for (var k = 0; k < 4; ++k) + { + var next = Tuple.Create(position.Item1 + paths[k, 0], position.Item2 + paths[k, 1]); + if (next.Item1 >= 0 && next.Item1 < lenI && next.Item2 >= 0 && next.Item2 < lenJ && grid[next.Item1][next.Item2] == '1') + { + grid[next.Item1][next.Item2] = '0'; + queue.Enqueue(next); + } + } + } + } + } + } + return result; + } +} \ No newline at end of file diff --git a/solution/0201.Bitwise AND of Numbers Range/Solution.cs b/solution/0201.Bitwise AND of Numbers Range/Solution.cs new file mode 100644 index 0000000000000..040e5ac576500 --- /dev/null +++ b/solution/0201.Bitwise AND of Numbers Range/Solution.cs @@ -0,0 +1,13 @@ +public class Solution { + public int RangeBitwiseAnd(int m, int n) { + var and = m & n; + var xor = m ^ n; + var temp = 0; + while (xor > 0) + { + temp = (temp << 1) + 1; + xor >>= 1; + } + return and & (~temp); + } +} \ No newline at end of file diff --git a/solution/0203.Remove Linked List Elements/Solution.cs b/solution/0203.Remove Linked List Elements/Solution.cs new file mode 100644 index 0000000000000..9c0afd3f42027 --- /dev/null +++ b/solution/0203.Remove Linked List Elements/Solution.cs @@ -0,0 +1,25 @@ +public class Solution { + public ListNode RemoveElements(ListNode head, int val) { + ListNode newHead = null; + ListNode newTail = null; + var current = head; + while (current != null) + { + if (current.val != val) + { + if (newHead == null) + { + newHead = newTail = current; + } + else + { + newTail.next = current; + newTail = current; + } + } + current = current.next; + } + if (newTail != null) newTail.next = null; + return newHead; + } +} \ No newline at end of file diff --git a/solution/0204.Count Primes/Solution.cs b/solution/0204.Count Primes/Solution.cs new file mode 100644 index 0000000000000..f8be821a4c9ff --- /dev/null +++ b/solution/0204.Count Primes/Solution.cs @@ -0,0 +1,18 @@ +public class Solution { + public int CountPrimes(int n) { + var count = 0; + var notPrime = new bool[n]; + for (var i = 2; i < n; ++i) + { + if (!notPrime[i]) + { + ++count; + for (var j = i + i; j < n; j += i) + { + notPrime[j] = true; + } + } + } + return count; + } +} \ No newline at end of file diff --git a/solution/0205.Isomorphic Strings/Solution.cs b/solution/0205.Isomorphic Strings/Solution.cs new file mode 100644 index 0000000000000..79a7524fea007 --- /dev/null +++ b/solution/0205.Isomorphic Strings/Solution.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; + +public class Solution { + public bool IsIsomorphic(string s, string t) { + if (s.Length != t.Length) return false; + var dict1 = new Dictionary(); + var dict2 = new Dictionary(); + for (var i = 0; i < s.Length; ++i) + { + char mapping1; + char mapping2; + var found1 = dict1.TryGetValue(s[i], out mapping1); + var found2 = dict2.TryGetValue(t[i], out mapping2); + if (found1 ^ found2) return false; + if (!found1) + { + dict1.Add(s[i], t[i]); + dict2.Add(t[i], s[i]); + } + else if (mapping1 != t[i] || mapping2 != s[i]) + { + return false; + } + } + return true; + } +} \ No newline at end of file diff --git a/solution/0206.Reverse Linked List/Solution.cs b/solution/0206.Reverse Linked List/Solution.cs new file mode 100644 index 0000000000000..65f169c994ec8 --- /dev/null +++ b/solution/0206.Reverse Linked List/Solution.cs @@ -0,0 +1,13 @@ +public class Solution { + public ListNode ReverseList(ListNode head) { + ListNode newHead = null; + while (head != null) + { + var next = head.next; + head.next = newHead; + newHead = head; + head = next; + } + return newHead; + } +} \ No newline at end of file diff --git a/solution/0207.Course Schedule/Solution.cs b/solution/0207.Course Schedule/Solution.cs new file mode 100644 index 0000000000000..3532d64d34341 --- /dev/null +++ b/solution/0207.Course Schedule/Solution.cs @@ -0,0 +1,44 @@ +using System.Collections.Generic; + +public class Solution { + public bool CanFinish(int numCourses, int[][] prerequisites) { + var indegree = new int[numCourses]; + var edgeCount = prerequisites.Length; + var edge = new List[numCourses]; + for (var i = 0; i < edgeCount; ++i) + { + var child = prerequisites[i][0]; + var parent = prerequisites[i][1]; + if (edge[parent] == null) + { + edge[parent] = new List(); + } + edge[parent].Add(child); + ++indegree[child]; + } + + var queue = new Queue(); + for (var i = 0; i < numCourses; ++i) + { + if (indegree[i] == 0) queue.Enqueue(i); + } + + var count = 0; + while (queue.Count > 0) + { + var node = queue.Dequeue(); + ++count; + if (edge[node] != null) + { + foreach (var next in edge[node]) + { + if (--indegree[next] == 0) + { + queue.Enqueue(next); + } + } + } + } + return count == numCourses; + } +} \ No newline at end of file diff --git a/solution/0208. Implement Trie (Prefix Tree)/Solution.cs b/solution/0208. Implement Trie (Prefix Tree)/Solution.cs new file mode 100644 index 0000000000000..4856875ea8709 --- /dev/null +++ b/solution/0208. Implement Trie (Prefix Tree)/Solution.cs @@ -0,0 +1,63 @@ +using System.Collections.Generic; +using System.Linq; + +class TrieNode { + public bool IsEnd { get; set; } + public TrieNode[] Children { get; set; } + public TrieNode() { + Children = new TrieNode[26]; + } +} + +public class Trie { + private TrieNode root; + + public Trie() { + root = new TrieNode(); + } + + public void Insert(string word) { + var node = root; + for (var i = 0; i < word.Length; ++i) + { + TrieNode nextNode; + var index = word[i] - 'a'; + nextNode = node.Children[index]; + if (nextNode == null) + { + nextNode = new TrieNode(); + node.Children[index] = nextNode; + } + node = nextNode; + } + node.IsEnd = true; + } + + public bool Search(string word) { + var node = root; + for (var i = 0; i < word.Length; ++i) + { + var nextNode = node.Children[word[i] - 'a']; + if (nextNode == null) + { + return false; + } + node = nextNode; + } + return node.IsEnd; + } + + public bool StartsWith(string word) { + var node = root; + for (var i = 0; i < word.Length; ++i) + { + var nextNode = node.Children[word[i] - 'a']; + if (nextNode == null) + { + return false; + } + node = nextNode; + } + return node.IsEnd || node.Children.Any(c => c != null); + } +} \ No newline at end of file diff --git a/solution/0209.Minimum Size Subarray Sum/Solution.cs b/solution/0209.Minimum Size Subarray Sum/Solution.cs new file mode 100644 index 0000000000000..e88bb30fd5faf --- /dev/null +++ b/solution/0209.Minimum Size Subarray Sum/Solution.cs @@ -0,0 +1,26 @@ +using System; + +public class Solution { + public int MinSubArrayLen(int s, int[] nums) { + var result = int.MaxValue; + var l = 0; + var r = -1; + var sum = 0; + while (r + 1 < nums.Length) + { + sum += nums[++r]; + while (sum - nums[l] >= s) + { + sum -= nums[l++]; + } + if (sum >= s) + { + result = Math.Min(result, r - l + 1); + sum -= nums[l++]; + } + } + + if (result == int.MaxValue) result = 0; + return result; + } +} \ No newline at end of file diff --git a/solution/0210.Course Schedule II/Solution.cs b/solution/0210.Course Schedule II/Solution.cs new file mode 100644 index 0000000000000..dc598f0d84b51 --- /dev/null +++ b/solution/0210.Course Schedule II/Solution.cs @@ -0,0 +1,45 @@ +using System.Collections.Generic; + +public class Solution { + public int[] FindOrder(int numCourses, int[][] prerequisites) { + var indegree = new int[numCourses]; + var edgeCount = prerequisites.Length; + var edge = new List[numCourses]; + for (var i = 0; i < edgeCount; ++i) + { + var child = prerequisites[i][0]; + var parent = prerequisites[i][1]; + if (edge[parent] == null) + { + edge[parent] = new List(); + } + edge[parent].Add(child); + ++indegree[child]; + } + + var queue = new Queue(); + for (var i = 0; i < numCourses; ++i) + { + if (indegree[i] == 0) queue.Enqueue(i); + } + + var result = new int[numCourses]; + var count = 0; + while (queue.Count > 0) + { + var node = queue.Dequeue(); + result[count++] = node; + if (edge[node] != null) + { + foreach (var next in edge[node]) + { + if (--indegree[next] == 0) + { + queue.Enqueue(next); + } + } + } + } + return count == numCourses ? result : new int[0]; + } +} \ No newline at end of file diff --git a/solution/0211. Add and Search Word - Data structure design/Solution.cs b/solution/0211. Add and Search Word - Data structure design/Solution.cs new file mode 100644 index 0000000000000..d0d04495d1ed2 --- /dev/null +++ b/solution/0211. Add and Search Word - Data structure design/Solution.cs @@ -0,0 +1,67 @@ +using System.Collections.Generic; +using System.Linq; + +class TrieNode { + public bool IsEnd { get; set; } + public TrieNode[] Children { get; set; } + public TrieNode() { + Children = new TrieNode[26]; + } +} + +public class WordDictionary { + private TrieNode root; + + public WordDictionary() { + root = new TrieNode(); + } + + public void AddWord(string word) { + var node = root; + for (var i = 0; i < word.Length; ++i) + { + TrieNode nextNode; + var index = word[i] - 'a'; + nextNode = node.Children[index]; + if (nextNode == null) + { + nextNode = new TrieNode(); + node.Children[index] = nextNode; + } + node = nextNode; + } + node.IsEnd = true; + } + + public bool Search(string word) { + var queue = new Queue(); + queue.Enqueue(root); + for (var i = 0; i < word.Length; ++i) + { + var count = queue.Count; + while (count-- > 0) + { + var node = queue.Dequeue(); + if (word[i] == '.') + { + foreach (var nextNode in node.Children) + { + if (nextNode != null) + { + queue.Enqueue(nextNode); + } + } + } + else + { + var nextNode = node.Children[word[i] - 'a']; + if (nextNode != null) + { + queue.Enqueue(nextNode); + } + } + } + } + return queue.Any(n => n.IsEnd); + } +} \ No newline at end of file diff --git a/solution/0212.Word Search II/Solution.cs b/solution/0212.Word Search II/Solution.cs new file mode 100644 index 0000000000000..1737677fa4fd3 --- /dev/null +++ b/solution/0212.Word Search II/Solution.cs @@ -0,0 +1,82 @@ +// https://leetcode.com/problems/word-search-ii/ + +using System.Collections.Generic; +using System.Linq; +using System.Text; + +public class WordDictionary : Dictionary +{ + public bool CanEnd = false; +} + +public class Solution +{ + public IList FindWords(char[][] board, string[] words) + { + var dict = new WordDictionary(); + foreach (var word in words) + { + var d = dict; + for (var i = 0; i < word.Length; ++i) + { + WordDictionary d2; + if (d.TryGetValue(word[i], out d2)) + { + d = d2; + } + else + { + d[word[i]] = new WordDictionary(); + d = d[word[i]]; + } + } + d.CanEnd = true; + } + + var results = new List(); + for (var i = 0; i < board.Length; ++i) + { + for (var j = 0; j < board[0].Length; ++j) + { + var sb = new StringBuilder(); + foreach (var word in FindWords_Search(board, i, j, sb, dict)) + { + results.Add(word); + } + } + } + // TODO: remove duplicates + return results.Distinct().ToList(); + } + + private readonly int[,] FindWords_SearchPath = new int[4, 2] { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } }; + + private IEnumerable FindWords_Search(char[][] board, int i, int j, StringBuilder sb, WordDictionary dict) + { + WordDictionary childDict; + if (dict.Keys.Count > 0 && char.IsLower(board[i][j]) && dict.TryGetValue(board[i][j], out childDict)) + { + sb.Append(board[i][j]); + if (childDict.CanEnd) + { + yield return sb.ToString(); + } + + board[i][j] = char.ToUpper(board[i][j]); + for (var k = 0; k < 4; ++k) + { + var newI = i + FindWords_SearchPath[k, 0]; + var newJ = j + FindWords_SearchPath[k, 1]; + if (newI >= 0 && newI < board.Length && newJ >= 0 && newJ < board[0].Length) + { + foreach (var word in FindWords_Search(board, newI, newJ, sb, childDict)) + { + yield return word; + } + } + } + sb.Remove(sb.Length - 1, 1); + board[i][j] = char.ToLower(board[i][j]); + } + } +} \ No newline at end of file diff --git a/solution/0214.Shortest Palindrome/Solution.cs b/solution/0214.Shortest Palindrome/Solution.cs new file mode 100644 index 0000000000000..c33ad4ae50914 --- /dev/null +++ b/solution/0214.Shortest Palindrome/Solution.cs @@ -0,0 +1,39 @@ +// https://leetcode.com/problems/shortest-palindrome/ + +using System.Text; + +public partial class Solution +{ + public string ShortestPalindrome(string s) + { + for (var i = s.Length - 1; i >= 0; --i) + { + var k = i; + var j = 0; + while (j < k) + { + if (s[j] == s[k]) + { + ++j; + --k; + } + else + { + break; + } + } + if (j >= k) + { + var sb = new StringBuilder(s.Length * 2 - i - 1); + for (var l = s.Length - 1; l >= i + 1; --l) + { + sb.Append(s[l]); + } + sb.Append(s); + return sb.ToString(); + } + } + + return string.Empty; + } +} \ No newline at end of file diff --git a/solution/0216.Combination Sum III/Solution.cs b/solution/0216.Combination Sum III/Solution.cs new file mode 100644 index 0000000000000..4c8778e40c91e --- /dev/null +++ b/solution/0216.Combination Sum III/Solution.cs @@ -0,0 +1,59 @@ +using System.Collections.Generic; + +public class Solution +{ + public IList> CombinationSum3(int k, int n) + { + if (n == 0 || k == 0) return new IList[0]; + + var paths = new List[n + 1, k + 1]; + paths[0, 0] = new List(); + for (var c = 1; c <= 9; ++c) + { + for (var j = n; j >= c; --j) + { + for (var kk = 1; kk <= k; ++kk) + { + if (paths[j - c, kk - 1] != null) + { + if (paths[j, kk] == null) + { + paths[j, kk] = new List(); + } + paths[j, kk].Add(c); + } + } + } + } + + var results = new List>(); + if (paths[n, k] != null && paths[n, k].Count > 0) GenerateResults(results, new Stack(), paths, k, n, paths[n, k].Count - 1); + return results; + } + + private void GenerateResults(IList> results, Stack result, List[,] paths, int k, int n, + int maxIndex) + { + if (n == 0) + { + results.Add(new List(result)); + return; + } + for (var i = maxIndex; i >= 0; --i) + { + var value = paths[n, k][i]; + result.Push(value); + var nextMaxIndex = paths[n - value, k - 1].BinarySearch(value); + if (nextMaxIndex >= 0) + { + --nextMaxIndex; + } + else if (nextMaxIndex < 0) + { + nextMaxIndex = ~nextMaxIndex - 1; + } + GenerateResults(results, result, paths, k - 1, n - value, nextMaxIndex); + result.Pop(); + } + } +} \ No newline at end of file diff --git a/solution/0217.Contains Duplicate/Solution.cs b/solution/0217.Contains Duplicate/Solution.cs new file mode 100644 index 0000000000000..fddf9b351a8a1 --- /dev/null +++ b/solution/0217.Contains Duplicate/Solution.cs @@ -0,0 +1,11 @@ +// https://leetcode.com/problems/contains-duplicate/ + +using System.Linq; + +public partial class Solution +{ + public bool ContainsDuplicate(int[] nums) + { + return nums.Distinct().Count() < nums.Length; + } +} diff --git a/solution/0219.Contains Duplicate II/Solution.cs b/solution/0219.Contains Duplicate II/Solution.cs new file mode 100644 index 0000000000000..8bc22ff42060e --- /dev/null +++ b/solution/0219.Contains Duplicate II/Solution.cs @@ -0,0 +1,37 @@ +// https://leetcode.com/problems/contains-duplicate-ii/ + +using System; +using System.Collections.Generic; +using System.Linq; + +public partial class Solution +{ + public bool ContainsNearbyDuplicate(int[] nums, int k) + { + //var sorted = nums.Select((n, i) => Tuple.Create(n, i)).OrderBy(t => t.Item1).ThenBy(t => t.Item2).ToList(); + //for (var i = 1; i < sorted.Count; ++i) + //{ + // if (sorted[i - 1].Item1 == sorted[i].Item1 && sorted[i].Item2 - sorted[i - 1].Item2 <= k) + // { + // return true; + // } + //} + //return false; + + if (k <= 0) return false; + var index = new HashSet(); + for (int i = 0; i < nums.Length; ++i) + { + if (index.Contains(nums[i])) + { + return true; + } + if (index.Count == k) + { + index.Remove(nums[i - k]); + } + index.Add(nums[i]); + } + return false; + } +} diff --git a/solution/0220.Contains Duplicate III/Solution.cs b/solution/0220.Contains Duplicate III/Solution.cs new file mode 100644 index 0000000000000..80e680634aa37 --- /dev/null +++ b/solution/0220.Contains Duplicate III/Solution.cs @@ -0,0 +1,35 @@ +// https://leetcode.com/problems/contains-duplicate-iii/ + +using System.Collections.Generic; + +public partial class Solution +{ + public bool ContainsNearbyAlmostDuplicate(int[] nums, int k, int t) + { + + if (k <= 0 || t < 0) return false; + var index = new SortedList(); + for (int i = 0; i < nums.Length; ++i) + { + if (index.ContainsKey(nums[i])) + { + return true; + } + index.Add(nums[i], null); + var j = index.IndexOfKey(nums[i]); + if (j > 0 && (long)nums[i] - index.Keys[j - 1] <= t) + { + return true; + } + if (j < index.Count - 1 && (long)index.Keys[j + 1] - nums[i] <= t) + { + return true; + } + if (index.Count > k) + { + index.Remove(nums[i - k]); + } + } + return false; + } +} diff --git a/solution/0221.Maximal Square/Solution.cs b/solution/0221.Maximal Square/Solution.cs new file mode 100644 index 0000000000000..997688aa8522f --- /dev/null +++ b/solution/0221.Maximal Square/Solution.cs @@ -0,0 +1,40 @@ +// https://leetcode.com/problems/maximal-square/ + +using System; + +public partial class Solution +{ + public int MaximalSquare(char[][] matrix) + { + var lengthI = matrix.Length; + var lengthJ = lengthI == 0 ? 0 : matrix[0].Length; + if (lengthI == 0 || lengthJ == 0) return 0; + + var lenI = new int[lengthI, lengthJ]; + var lenJ = new int[lengthI, lengthJ]; + var f = new int[lengthI, lengthJ]; + var maxSideLength = 0; + for (var i = 0; i < lengthI; ++i) + { + for (var j = 0; j < lengthJ ; ++j) + { + if (matrix[i][j] == '1') + { + lenI[i, j] = i == 0 ? 1 : lenI[i - 1, j] + 1; + lenJ[i, j] = j == 0 ? 1 : lenJ[i, j - 1] + 1; + if (i == 0 || j == 0) + { + f[i, j] = 1; + } + else + { + f[i, j] = Math.Min(Math.Min(f[i - 1, j - 1] + 1, lenI[i, j]), lenJ[i, j]); + } + if (f[i, j] > maxSideLength) maxSideLength = f[i, j]; + } + } + } + + return maxSideLength * maxSideLength; + } +} \ No newline at end of file diff --git a/solution/0222.Count Complete Tree Nodes/Solution.cs b/solution/0222.Count Complete Tree Nodes/Solution.cs new file mode 100644 index 0000000000000..9c8282102b2b0 --- /dev/null +++ b/solution/0222.Count Complete Tree Nodes/Solution.cs @@ -0,0 +1,38 @@ +// https://leetcode.com/problems/count-complete-tree-nodes/ + +using System; + +public class Solution +{ + public int CountNodes(TreeNode root) + { + if (root == null) return 0; + var lastNodeOffset = CountNodes_GetLastNodeOffset(root, 0); + var totalDepth = CountNodes_GetDeepth(root); + return (int)Math.Pow(2, totalDepth - 1) - 1 + lastNodeOffset; + } + + private int CountNodes_GetLastNodeOffset(TreeNode node, int offset) + { + if (node == null) return offset; + if (node.left == null) return offset + 1; + var leftDepth = CountNodes_GetDeepth(node.left); + var rightDepth = CountNodes_GetDeepth(node.right); + if (leftDepth > rightDepth) + { + return CountNodes_GetLastNodeOffset(node.left, offset); + } + return CountNodes_GetLastNodeOffset(node.right, offset + (int)Math.Pow(2, leftDepth - 1)); + } + + private int CountNodes_GetDeepth(TreeNode node) + { + var depth = 0; + while (node != null) + { + ++depth; + node = node.left; + } + return depth; + } +} diff --git a/solution/0223.Rectangle Area/Solution.cs b/solution/0223.Rectangle Area/Solution.cs new file mode 100644 index 0000000000000..73410231b7eb5 --- /dev/null +++ b/solution/0223.Rectangle Area/Solution.cs @@ -0,0 +1,20 @@ +// https://leetcode.com/problems/rectangle-area/ + +using System; + +public partial class Solution +{ + public int ComputeArea(int A, int B, int C, int D, int E, int F, int G, int H) + { + var area = (long)(C - A) * (D - B) + (G - E) * (H - F); + var overlapA = Math.Max(A, E); + var overlapB = Math.Max(B, F); + var overlapC = Math.Min(C, G); + var overlapD = Math.Min(D, H); + if (overlapA < overlapC && overlapB < overlapD) + { + area -= (overlapC - overlapA) * (overlapD - overlapB); + } + return (int)area; + } +} \ No newline at end of file diff --git a/solution/0224.Basic Calculator/Solution.cs b/solution/0224.Basic Calculator/Solution.cs new file mode 100644 index 0000000000000..62b4cc68297bd --- /dev/null +++ b/solution/0224.Basic Calculator/Solution.cs @@ -0,0 +1,62 @@ +using System.Collections.Generic; + +public class Solution { + public int Calculate(string s) { + var numbers = new Stack(); + var symbols = new Stack(); + int number = -1; + for (var i = 0; i <= s.Length; ++i) + { + var ch = i < s.Length ? s[i] : ' '; + if (char.IsDigit(ch)) + { + if (number == -1) number = 0; + number = number * 10 + ch - '0'; + } + else + { + if (number != -1) + { + numbers.Push(number); + while (symbols.Count > 0 && symbols.Peek() != '(') + { + var symbol = symbols.Pop(); + if (symbol == '+') + { + numbers.Push(numbers.Pop() + numbers.Pop()); + } + else + { + numbers.Push(-(numbers.Pop() - numbers.Pop())); + } + } + number = -1; + } + if (char.IsWhiteSpace(ch)) continue; + + if (ch == ')') + { + symbols.Pop(); + while (symbols.Count > 0 && symbols.Peek() != '(') + { + var symbol = symbols.Pop(); + if (symbol == '+') + { + numbers.Push(numbers.Pop() + numbers.Pop()); + } + else + { + numbers.Push(-(numbers.Pop() - numbers.Pop())); + } + } + } + else + { + symbols.Push(ch); + } + } + } + + return numbers.Pop(); + } +} \ No newline at end of file diff --git a/solution/0227.Basic Calculator II/Solution.cs b/solution/0227.Basic Calculator II/Solution.cs new file mode 100644 index 0000000000000..52259f172cbac --- /dev/null +++ b/solution/0227.Basic Calculator II/Solution.cs @@ -0,0 +1,84 @@ +using System.Collections.Generic; +using System.Linq; + +struct Element +{ + public char Op; + public int Number; + public Element(char op, int number) + { + Op = op; + Number = number; + } +} + +public class Solution { + public int Calculate(string s) { + var stack = new Stack(); + var readingNumber = false; + var number = 0; + var op = '+'; + foreach (var ch in ((IEnumerable)s).Concat(Enumerable.Repeat('+', 1))) + { + if (ch >= '0' && ch <= '9') + { + if (!readingNumber) + { + readingNumber = true; + number = 0; + } + number = (number * 10) + (ch - '0'); + } + else if (ch != ' ') + { + readingNumber = false; + if (op == '+' || op == '-') + { + if (stack.Count == 2) + { + var prev = stack.Pop(); + var first = stack.Pop(); + if (prev.Op == '+') + { + stack.Push(new Element(first.Op, first.Number + prev.Number)); + } + else // '-' + { + stack.Push(new Element(first.Op, first.Number - prev.Number)); + } + } + stack.Push(new Element(op, number)); + } + else + { + var prev = stack.Pop(); + if (op == '*') + { + stack.Push(new Element(prev.Op, prev.Number * number)); + } + else // '/' + { + stack.Push(new Element(prev.Op, prev.Number / number)); + } + } + op = ch; + } + } + + if (stack.Count == 2) + { + var second = stack.Pop(); + var first = stack.Pop(); + if (second.Op == '+') + { + stack.Push(new Element(first.Op, first.Number + second.Number)); + } + else // '-' + { + stack.Push(new Element(first.Op, first.Number - second.Number)); + } + } + + return stack.Peek().Number; + } +} \ No newline at end of file diff --git a/solution/0228.Summary Ranges/Solution.cs b/solution/0228.Summary Ranges/Solution.cs new file mode 100644 index 0000000000000..3e0230ac8ffd9 --- /dev/null +++ b/solution/0228.Summary Ranges/Solution.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; + +public class Solution { + public IList SummaryRanges(int[] nums) { + var result = new List(); + int? start = null; + for (var i = 0; i < nums.Length; ++i) + { + if (start == null) start = nums[i]; + if (i == nums.Length - 1 || nums[i] + 1 < nums[i + 1]) + { + result.Add(start == nums[i] ? start.ToString() : string.Format("{0}->{1}", start, nums[i])); + start = null; + } + } + return result; + } +} \ No newline at end of file diff --git a/solution/0229.Majority Element II/Solution.cs b/solution/0229.Majority Element II/Solution.cs new file mode 100644 index 0000000000000..9b75786b9974f --- /dev/null +++ b/solution/0229.Majority Element II/Solution.cs @@ -0,0 +1,44 @@ +using System.Collections.Generic; +using System.Linq; + +public class Solution { + public IList MajorityElement(int[] nums) { + if (nums.Length == 0) return new int[0]; + var targetIndices = new [] { nums.Length / 3, nums.Length - nums.Length / 3 - 1 }.Distinct().ToList(); + var candidates = Sort(nums, 0, nums.Length - 1, targetIndices).Distinct(); + return candidates.Where(c => nums.Count(n => n == c) > nums.Length / 3).ToList(); + } + + private IList Sort(int[] nums, int left, int right, IList targetIndices) + { + if (left == right) return new [] { nums[left] }; + var mid = nums[(left + right) / 2]; + var i = left; + var j = right; + while (i <= j) + { + while (nums[i] < mid) ++i; + while (nums[j] > mid) --j; + if (i <= j) + { + var temp = nums[i]; + nums[i] = nums[j]; + nums[j] = temp; + ++i; + --j; + } + } + var result = new List(); + var leftTargetIndices = new List(); + var rightTargetIndecies = new List(); + foreach (var targetIndex in targetIndices) + { + if (targetIndex <= j) leftTargetIndices.Add(targetIndex); + else if (targetIndex >= i) rightTargetIndecies.Add(targetIndex); + else result.Add(mid); + } + if (leftTargetIndices.Count > 0) result.AddRange(Sort(nums, left, j, leftTargetIndices)); + if (rightTargetIndecies.Count > 0) result.AddRange(Sort(nums, i, right, rightTargetIndecies)); + return result; + } +} \ No newline at end of file diff --git a/solution/0233.Number of Digit One/Solution.cs b/solution/0233.Number of Digit One/Solution.cs new file mode 100644 index 0000000000000..92638269267df --- /dev/null +++ b/solution/0233.Number of Digit One/Solution.cs @@ -0,0 +1,17 @@ +public class Solution { + public int CountDigitOne(int n) { + if (n <= 0) return 0; + if (n < 10) return 1; + return CountDigitOne(n / 10 - 1) * 10 + n / 10 + CountDigitOneOfN(n / 10) * (n % 10 + 1) + (n % 10 >= 1 ? 1 : 0); + } + + private int CountDigitOneOfN(int n) { + var count = 0; + while (n > 0) + { + if (n % 10 == 1) ++count; + n /= 10; + } + return count; + } +} \ No newline at end of file diff --git a/solution/0234.Palindrome Linked List/Solution.cs b/solution/0234.Palindrome Linked List/Solution.cs new file mode 100644 index 0000000000000..fc06343d983e0 --- /dev/null +++ b/solution/0234.Palindrome Linked List/Solution.cs @@ -0,0 +1,48 @@ +public class Solution { + public bool IsPalindrome(ListNode head) { + if (head == null) return true; + var count = Count(head); + var temp = head; + var c = 1; + while (c < count / 2) + { + ++c; + temp = temp.next; + } + var head2 = Reverse(temp.next); + temp.next = null; + + while (head != null && head2 != null) + { + if (head.val != head2.val) return false; + head = head.next; + head2 = head2.next; + } + return true; + } + + private int Count(ListNode head) + { + var count = 0; + while (head != null) + { + ++count; + head = head.next; + } + return count; + } + + private ListNode Reverse(ListNode head) + { + var temp = head; + head = null; + while (temp != null) + { + var temp2 = temp.next; + temp.next = head; + head = temp; + temp = temp2; + } + return head; + } +} \ No newline at end of file diff --git a/solution/0239.Sliding Window Maximum/Solution.cs b/solution/0239.Sliding Window Maximum/Solution.cs new file mode 100644 index 0000000000000..15052452592c9 --- /dev/null +++ b/solution/0239.Sliding Window Maximum/Solution.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; + +public class Solution { + public int[] MaxSlidingWindow(int[] nums, int k) { + if (nums.Length == 0) return new int[0]; + var result = new int[nums.Length - k + 1]; + var descOrderNums = new LinkedList(); + for (var i = 0; i < nums.Length; ++i) + { + if (i >= k && nums[i - k] == descOrderNums.First.Value) + { + descOrderNums.RemoveFirst(); + } + while (descOrderNums.Count > 0 && nums[i] > descOrderNums.Last.Value) + { + descOrderNums.RemoveLast(); + } + descOrderNums.AddLast(nums[i]); + if (i >= k - 1) + { + result[i - k + 1] = descOrderNums.First.Value; + } + } + return result; + } +} \ No newline at end of file diff --git a/solution/0241.Different Ways to Add Parentheses/Solution.cs b/solution/0241.Different Ways to Add Parentheses/Solution.cs new file mode 100644 index 0000000000000..c09ba31bf19d8 --- /dev/null +++ b/solution/0241.Different Ways to Add Parentheses/Solution.cs @@ -0,0 +1,61 @@ +using System.Collections.Generic; + +public class Solution { + public IList DiffWaysToCompute(string input) { + var values = new List(); + var operators = new List(); + var sum = 0; + foreach (var ch in input) + { + if (ch == '+' || ch == '-' || ch == '*') + { + values.Add(sum); + operators.Add(ch); + sum = 0; + } + else + { + sum = sum * 10 + ch - '0'; + } + } + values.Add(sum); + + var f = new List[values.Count, values.Count]; + for (var i = 0; i < values.Count; ++i) + { + f[i, i] = new List { values[i] }; + } + + for (var diff = 1; diff < values.Count; ++diff) + { + for (var left = 0; left + diff < values.Count; ++left) + { + var right = left + diff; + f[left, right] = new List(); + for (var i = left; i < right; ++i) + { + foreach (var leftValue in f[left, i]) + { + foreach (var rightValue in f[i + 1, right]) + { + switch (operators[i]) + { + case '+': + f[left, right].Add(leftValue + rightValue); + break; + case '-': + f[left, right].Add(leftValue - rightValue); + break; + case '*': + f[left, right].Add(leftValue * rightValue); + break; + } + } + } + } + } + } + + return f[0, values.Count - 1]; + } +} \ No newline at end of file diff --git a/solution/0273.Integer to English Words/Solution.cs b/solution/0273.Integer to English Words/Solution.cs new file mode 100644 index 0000000000000..e52511dc87e27 --- /dev/null +++ b/solution/0273.Integer to English Words/Solution.cs @@ -0,0 +1,88 @@ +using System.Collections.Generic; +using System.Linq; + +public class Solution { + private string[] bases = { "Thousand", "Million", "Billion" }; + public string NumberToWords(int num) { + if (num == 0) + { + return "Zero"; + } + var baseIndex = -1; + var parts = new List(); + while (num > 0) + { + var part = NumberToWordsInternal(num % 1000); + if (part.Length > 0 && baseIndex >= 0) + { + part = JoinParts(part, bases[baseIndex]); + } + parts.Add(part); + baseIndex++; + num /= 1000; + } + parts.Reverse(); + return JoinParts(parts); + } + + private string JoinParts(IEnumerable parts) + { + return string.Join(" ", parts.Where(p => p.Length > 0)); + } + + private string JoinParts(params string[] parts) + { + return JoinParts((IEnumerable)parts); + } + + private string NumberToWordsInternal(int num) + { + switch(num) + { + case 0: return ""; + case 1: return "One"; + case 2: return "Two"; + case 3: return "Three"; + case 4: return "Four"; + case 5: return "Five"; + case 6: return "Six"; + case 7: return "Seven"; + case 8: return "Eight"; + case 9: return "Nine"; + case 10: return "Ten"; + case 11: return "Eleven"; + case 12: return "Twelve"; + case 13: return "Thirteen"; + case 14: return "Fourteen"; + case 15: return "Fifteen"; + case 16: return "Sixteen"; + case 17: return "Seventeen"; + case 18: return "Eighteen"; + case 19: return "Nineteen"; + } + + if (num < 100) + { + string part1; + switch (num/10) + { + case 2: part1 = "Twenty"; break; + case 3: part1 = "Thirty"; break; + case 4: part1 = "Forty"; break; + case 5: part1 = "Fifty"; break; + case 6: part1 = "Sixty"; break; + case 7: part1 = "Seventy"; break; + case 8: part1 = "Eighty"; break; + case 9: default: part1 = "Ninety"; break; + } + var part2 = NumberToWordsInternal(num % 10); + return JoinParts(part1, part2); + } + + { + var part1 = NumberToWordsInternal(num / 100); + var part2 = NumberToWordsInternal(num % 100); + return JoinParts(part1, "Hundred", part2); + } + } +} \ No newline at end of file diff --git a/solution/0282.Expression Add Operators/Solution.cs b/solution/0282.Expression Add Operators/Solution.cs new file mode 100644 index 0000000000000..6244b16539c8b --- /dev/null +++ b/solution/0282.Expression Add Operators/Solution.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; + +public class Expression +{ + public long Value; + + public override string ToString() + { + return Value.ToString(); + } +} + +public class BinaryExpression : Expression +{ + public char Operator; + + public Expression LeftChild; + public Expression RightChild; + + public override string ToString() + { + return string.Format("{0}{1}{2}", LeftChild, Operator, RightChild); + } +} + +public class Solution { + public IList AddOperators(string num, int target) { + var results = new List(); + if (string.IsNullOrEmpty(num)) return results; + this.num = num; + this.results = new List[num.Length, num.Length, 3]; + foreach (var ex in Search(0, num.Length - 1, 0)) + { + if (ex.Value == target) + { + results.Add(ex.ToString()); + } + } + return results; + } + + private string num; + private List[,,] results; + + private List Search(int left, int right, int level) + { + if (results[left, right, level] != null) + { + return results[left, right, level]; + } + var result = new List(); + if (level < 2) + { + for (var i = left + 1; i <= right; ++i) + { + List leftResult, rightResult; + leftResult = Search(left, i - 1, level); + rightResult = Search(i, right, level + 1); + foreach (var l in leftResult) + { + foreach (var r in rightResult) + { + var newObjects = new List>(); + if (level == 0) + { + newObjects.Add(Tuple.Create('+', l.Value + r.Value)); + newObjects.Add(Tuple.Create('-', l.Value - r.Value)); + } + else + { + newObjects.Add(Tuple.Create('*', l.Value * r.Value)); + } + foreach (var newObject in newObjects) + { + result.Add(new BinaryExpression + { + Value = newObject.Item2, + Operator = newObject.Item1, + LeftChild = l, + RightChild = r + }); + } + } + } + } + } + else + { + if (left == right || num[left] != '0') + { + long x = 0; + for (var i = left; i <= right; ++i) + { + x = x * 10 + num[i] - '0'; + } + result.Add(new Expression + { + Value = x + }); + } + } + if (level < 2) + { + result.AddRange(Search(left, right, level + 1)); + } + return results[left, right, level] = result; + } +} \ No newline at end of file diff --git a/solution/0295.Find Median from Data Stream/Solution.cs b/solution/0295.Find Median from Data Stream/Solution.cs new file mode 100644 index 0000000000000..357b1dbd714d9 --- /dev/null +++ b/solution/0295.Find Median from Data Stream/Solution.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; + +public class Comparer : IComparer> +{ + public int Compare(Tuple x, Tuple y) + { + var result = x.Item1.CompareTo(y.Item1); + if (result != 0) + { + return result; + } + return x.Item2.CompareTo(y.Item2); + } +} + +public class MedianFinder { + + private SortedSet> smallerHeap = new SortedSet>(); + private SortedSet> biggerHeap = new SortedSet>(); + + private int index; + + public void AddNum(double num) { + if (smallerHeap.Count == 0 || smallerHeap.Max.Item1 >= num) + { + smallerHeap.Add(Tuple.Create(num, index++)); + } + else + { + biggerHeap.Add(Tuple.Create(num, index++)); + } + + if (smallerHeap.Count == biggerHeap.Count + 2) + { + biggerHeap.Add(smallerHeap.Max); + smallerHeap.Remove(smallerHeap.Max); + } + else if (biggerHeap.Count == smallerHeap.Count + 2) + { + smallerHeap.Add(biggerHeap.Min); + biggerHeap.Remove(biggerHeap.Min); + } + } + + public double FindMedian() { + if (smallerHeap.Count == biggerHeap.Count) + { + return (smallerHeap.Max.Item1 + biggerHeap.Min.Item1) / 2; + } + else if (smallerHeap.Count < biggerHeap.Count) + { + return biggerHeap.Min.Item1; + } + else + { + return smallerHeap.Max.Item1; + } + } +} \ No newline at end of file diff --git a/solution/0307.Range Sum Query - Mutable/Solution.cs b/solution/0307.Range Sum Query - Mutable/Solution.cs new file mode 100644 index 0000000000000..b15a1c9364a54 --- /dev/null +++ b/solution/0307.Range Sum Query - Mutable/Solution.cs @@ -0,0 +1,75 @@ +public class NumArray { + private int[] sums; + private int numsCount; + private int sumsCount; + + public NumArray(int[] nums) { + numsCount = nums.Length; + sumsCount = 1; + var x = numsCount; + while (x > 1) + { + x /= 2; + sumsCount *= 2; + } + sumsCount = sumsCount * 2 - 1 + numsCount; + sums = new int[sumsCount + 1]; + + for (var i = sumsCount; i > 0; --i) + { + if (i - sumsCount + numsCount - 1 >= 0) + { + sums[i] = nums[i - sumsCount + numsCount - 1]; + } + else + { + var l = i * 2; + var r = l + 1; + if (l <= sumsCount) + { + sums[i] += sums[l]; + if (r <= sumsCount) + { + sums[i] += sums[r]; + } + } + } + } + //System.Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(sums)); + } + + public void Update(int i, int val) { + var j = sumsCount - numsCount + i + 1; + sums[j] = val; + for (j /= 2; j > 0; j /= 2) + { + var l = j * 2; + var r = l + 1; + sums[j] = sums[l]; + if (r <= sumsCount) + { + sums[j] += sums[r]; + } + } + //System.Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(sums)); + } + + public int SumRange(int i, int j) { + return SumFromStart(j) - SumFromStart(i - 1); + } + + private int SumFromStart(int i) + { + if (i < 0) return 0; + var j = sumsCount - numsCount + i + 1; + var sum = sums[j]; + for (; j / 2 > 0; j /= 2) + { + if (j % 2 != 0) + { + sum += sums[j - 1]; + } + } + return sum; + } +} \ No newline at end of file diff --git a/solution/0335.Self Crossing/Solution.cs b/solution/0335.Self Crossing/Solution.cs new file mode 100644 index 0000000000000..a54b763521976 --- /dev/null +++ b/solution/0335.Self Crossing/Solution.cs @@ -0,0 +1,14 @@ +public class Solution { + public bool IsSelfCrossing(int[] x) { + for (var i = 3; i < x.Length; ++i) + { + if (x[i] >= x[i - 2] && x[i - 1] <= x[i - 3]) return true; + if (i > 3 && x[i] + x[i - 4] >= x[i - 2]) + { + if (x[i - 1] == x[i - 3]) return true; + if (i > 4 && x[i - 2] >= x[i - 4] && x[i - 1] <= x[i - 3] && x[i - 1] + x[i - 5] >= x[i - 3]) return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/solution/0336.Palindrome Pairs/Solution.cs b/solution/0336.Palindrome Pairs/Solution.cs new file mode 100644 index 0000000000000..8fba7db6f68b1 --- /dev/null +++ b/solution/0336.Palindrome Pairs/Solution.cs @@ -0,0 +1,50 @@ +using System.Collections.Generic; +using System.Linq; + +public class Solution { + public IList> PalindromePairs(string[] words) { + var results = new List>(); + var reverseDict = words.Select((w, i) => new {Word = w, Index = i}).ToDictionary(w => new string(w.Word.Reverse().ToArray()), w => w.Index); + + for (var i = 0; i < words.Length; ++i) + { + var word = words[i]; + for (var j = 0; j <= word.Length; ++j) + { + if (j > 0 && IsPalindrome(word, 0, j - 1)) + { + var suffix = word.Substring(j); + int pairIndex; + if (reverseDict.TryGetValue(suffix, out pairIndex) && i != pairIndex) + { + results.Add(new [] { pairIndex, i}); + } + } + if (IsPalindrome(word, j, word.Length - 1)) + { + var prefix = word.Substring(0, j); + int pairIndex; + if (reverseDict.TryGetValue(prefix, out pairIndex) && i != pairIndex) + { + results.Add(new [] { i, pairIndex}); + } + } + } + } + + return results; + } + + private bool IsPalindrome(string word, int startIndex, int endIndex) + { + var i = startIndex; + var j = endIndex; + while (i < j) + { + if (word[i] != word[j]) return false; + ++i; + --j; + } + return true; + } +} \ No newline at end of file diff --git a/solution/0365.Water and Jug Problem/Solution.cs b/solution/0365.Water and Jug Problem/Solution.cs new file mode 100644 index 0000000000000..bfd1a08231e61 --- /dev/null +++ b/solution/0365.Water and Jug Problem/Solution.cs @@ -0,0 +1,25 @@ +using System; + +public class Solution { + public bool CanMeasureWater(int x, int y, int z) { + if (x == 0 || y == 0) return z == x || z == y; + var gcd = GetGcd(x, y); + return z >= 0 && z <= x + y && z % gcd == 0; + } + + private int GetGcd(int x, int y) + { + while (x > 0) + { + var quotient = x / y; + var reminder = x % y; + if (reminder == 0) + { + return y; + } + x = y; + y = reminder; + } + throw new Exception("Invalid x or y"); + } +} \ No newline at end of file