├── C++ ├── o1-check-power-of-2.cpp ├── coins-in-a-line.cpp ├── flip-bits.cpp ├── count-1-in-binary.cpp ├── trailing-zeros.cpp ├── move-zeroes.cpp ├── unique-characters.cpp ├── ugly-number.cpp ├── jump-game.cpp ├── maximum-subarray.cpp ├── update-bits.cpp ├── fibonacci.cpp ├── single-number-ii.cpp ├── wiggle-sort.cpp ├── minimum-subarray.cpp ├── partition-array.cpp ├── sort-letters-by-case.cpp ├── hash-function.cpp ├── length-of-last-word.cpp ├── rotate-string.cpp ├── remove-element.cpp ├── left-pad.cpp ├── reverse-integer.cpp ├── partition-array-by-odd-and-even.cpp ├── find-peak-element.cpp ├── singleton.cpp ├── majority-number.cpp ├── subarray-sum.cpp ├── sort-colors.cpp ├── backpack-vi.cpp ├── single-number.cpp ├── plus-one.cpp ├── remove-duplicates-from-sorted-array.cpp ├── maximum-depth-of-binary-tree.cpp ├── maximum-product-subarray.cpp ├── valid-palindrome.cpp ├── happy-number.cpp ├── string-permutation.cpp ├── median.cpp ├── implement-queue-by-two-stacks.cpp ├── container-with-most-water.cpp ├── fizz-buzz.cpp ├── 2-sum.cpp ├── two-strings-are-anagrams.cpp ├── paint-fence.cpp ├── count-and-say.cpp ├── palindrome-partitioning-ii.cpp ├── delete-node-in-the-middle-of-singly-linked-list.cpp ├── longest-words.cpp ├── a-b-problem.cpp ├── candy.cpp ├── reorder-array-to-construct-the-minimum-number.cpp ├── remove-duplicates-from-sorted-array-ii.cpp ├── cosine-similarity.cpp ├── find-minimum-in-rotated-sorted-array-ii.cpp ├── largest-number.cpp ├── clone-binary-tree.cpp ├── reverse-linked-list.cpp ├── integer-to-roman.cpp ├── linked-list-cycle.cpp ├── roman-to-integer.cpp ├── merge-sorted-array.cpp ├── anagrams.cpp ├── permutation-index.cpp ├── identical-binary-tree.cpp ├── jump-game-ii.cpp ├── remove-duplicates-from-sorted-list.cpp ├── sliding-window-maximum.cpp ├── house-robber.cpp ├── decode-ways.cpp ├── remove-linked-list-elements.cpp ├── minimum-depth-of-binary-tree.cpp ├── toy-factory.cpp ├── add-binary.cpp ├── longest-substring-with-at-most-k-distinct-characters.cpp ├── word-break.cpp ├── swap-nodes-in-pairs.cpp ├── recover-rotated-sorted-array.cpp ├── continuous-subarray-sum.cpp ├── reverse-words-in-a-string.cpp ├── flatten-binary-tree-to-linked-list.cpp ├── minimum-path-sum.cpp ├── largest-rectangle-in-histogram.cpp ├── valid-parentheses.cpp ├── combinations.cpp ├── two-lists-sum.cpp ├── longest-increasing-continuous-subsequence.cpp ├── subsets-ii.cpp ├── house-robber-iii.cpp ├── rotate-list.cpp ├── house-robber-ii.cpp ├── nth-to-last-node-in-list.cpp ├── unique-paths-ii.cpp ├── dices-sum.cpp ├── longest-substring-without-repeating-characters.cpp ├── gray-code.cpp ├── search-a-2d-matrix-ii.cpp ├── validate-binary-search-tree.cpp ├── space-replacement.cpp ├── k-sum-ii.cpp ├── assignment-operator-overloading-c-only.cpp ├── generate-parentheses.cpp ├── merge-two-sorted-lists.cpp ├── wiggle-sort-ii.cpp ├── max-tree.cpp ├── find-the-missing-number.cpp ├── combination-sum.cpp ├── remove-duplicates-from-sorted-list-ii.cpp ├── string-to-integeratoi.cpp ├── sort-colors-ii.cpp ├── super-ugly-number.cpp ├── burst-balloons.cpp ├── balanced-binary-tree.cpp ├── wood-cut.cpp ├── next-permutation-ii.cpp ├── perfect-squares.cpp ├── partition-list.cpp ├── fast-power.cpp ├── merge-intervals.cpp ├── paint-house.cpp ├── unique-binary-search-trees.cpp ├── insertion-sort-list.cpp ├── evaluate-reverse-polish-notation.cpp ├── remove-nth-node-from-end-of-list.cpp ├── gas-station.cpp ├── permutations-ii.cpp ├── merge-sorted-array-ii.cpp ├── powx-n.cpp ├── maximal-square.cpp ├── n-queens-ii.cpp ├── lowest-common-ancestor.cpp ├── clone-graph.cpp ├── longest-common-substring.cpp ├── segment-tree-query-ii.cpp ├── segment-tree-query.cpp ├── segment-tree-build.cpp ├── triangle.cpp ├── binary-representation.cpp ├── combination-sum-ii.cpp ├── permutation-sequence.cpp ├── print-numbers-by-recursion.cpp ├── longest-common-subsequence.cpp ├── reverse-linked-list-ii.cpp ├── binary-search-tree-iterator.cpp ├── find-minimum-in-rotated-sorted-array.cpp ├── binary-tree-path-sum.cpp ├── intersection-of-two-linked-lists.cpp ├── lru-cache.cpp ├── maximum-subarray-ii.cpp ├── reverse-nodes-in-k-group.cpp ├── backpack.cpp ├── binary-tree-level-order-traversal.cpp ├── next-permutation.cpp ├── palindrome-partitioning.cpp ├── rotate-image.cpp ├── insert-interval.cpp ├── binary-tree-maximum-path-sum.cpp ├── previous-permutation.cpp ├── longest-consecutive-sequence.cpp ├── subsets.cpp ├── triangle-count.cpp ├── segment-tree-modify.cpp ├── longest-common-prefix.cpp ├── simplify-path.cpp ├── binary-tree-level-order-traversal-ii.cpp ├── shape-factory.cpp ├── convert-binary-search-tree-to-doubly-linked-list.cpp ├── copy-list-with-random-pointer.cpp ├── first-missing-positive.cpp ├── max-points-on-a-line.cpp ├── graph-valid-tree.cpp ├── palindrome-linked-list.cpp ├── backpack-ii.cpp ├── minimum-adjustment-cost.cpp ├── number-of-islands.cpp ├── flatten-list.cpp ├── 3-sum-closest.cpp ├── copy-books.cpp ├── interleaving-positive-and-negative-numbers.cpp ├── sort-integers.cpp ├── subarray-sum-closest.cpp ├── the-smallest-difference.cpp ├── binary-tree-paths.cpp ├── sort-list.cpp ├── 3-sum.cpp ├── compare-strings.cpp ├── find-the-connected-component-in-the-undirected-graph.cpp ├── heapify.cpp └── restore-ip-addresses.cpp ├── Python ├── cosine-similarity.py ├── single-number-iii.py ├── find-peak-element.py ├── backpack.py └── maximum-gap.py └── LICENSE.md /C++/o1-check-power-of-2.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(1) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /* 7 | * @param n: An integer 8 | * @return: True or false 9 | */ 10 | bool checkPowerOf2(int n) { 11 | return n > 0 && (n & (n - 1)) == 0; 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /C++/coins-in-a-line.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(1) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param n: an integer 8 | * @return: a boolean which equals to true if the first player will win 9 | */ 10 | bool firstWillWin(int n) { 11 | return n % 3 != 0; 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /C++/flip-bits.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(logn) = O(32) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | *@param a, b: Two integer 8 | *return: An integer 9 | */ 10 | int bitSwapRequired(int a, int b) { 11 | int cnt = 0; 12 | for (int c = a ^ b; c != 0; c &= c - 1) { 13 | ++cnt; 14 | } 15 | return cnt; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /C++/count-1-in-binary.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(logn) = O(32) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param num: an integer 8 | * @return: an integer, the number of ones in num 9 | */ 10 | int countOnes(int num) { 11 | int count = 0; 12 | for (; num; num &= num - 1) { 13 | ++count; 14 | } 15 | return count; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /C++/trailing-zeros.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(logn) = O(1) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | // param n : description of n 7 | // return: description of return 8 | long long trailingZeros(long long n) { 9 | long long zero_num = 0; 10 | while (n > 0) { 11 | n /= 5; 12 | zero_num += n; 13 | } 14 | return zero_num; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /C++/move-zeroes.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param nums an integer array 8 | * @return nothing, do this in-place 9 | */ 10 | void moveZeroes(vector& nums) { 11 | int pos = 0; 12 | for (auto& num : nums) { 13 | if (num) { 14 | swap(nums[pos++], num); 15 | } 16 | } 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /C++/unique-characters.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | #include 5 | 6 | class Solution { 7 | public: 8 | /** 9 | * @param str: a string 10 | * @return: a boolean 11 | */ 12 | bool isUnique(string &str) { 13 | bitset<256> lookup; 14 | for (const auto& c : str) { 15 | if (lookup[c]) { 16 | return false; 17 | } 18 | lookup.flip(c); 19 | } 20 | 21 | return true; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /C++/ugly-number.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(logn) = O(1) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param num an integer 8 | * @return true if num is an ugly number or false 9 | */ 10 | bool isUgly(int num) { 11 | if (num == 0) { 12 | return false; 13 | } 14 | for (const auto& i : {2, 3, 5}) { 15 | while (num % i == 0) { 16 | num /= i; 17 | } 18 | } 19 | return num == 1; 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /C++/jump-game.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param A: A list of integers 8 | * @return: The boolean answer 9 | */ 10 | bool canJump(vector A) { 11 | int reachable = 0; 12 | for (int i = 0; i < A.size(); ++i) { 13 | if (i > reachable) { 14 | return false; 15 | } 16 | reachable = max(reachable, i + A[i]); 17 | } 18 | 19 | return true; 20 | } 21 | }; 22 | 23 | -------------------------------------------------------------------------------- /C++/maximum-subarray.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param nums: A list of integers 8 | * @return: A integer indicate the sum of max subarray 9 | */ 10 | int maxSubArray(vector nums) { 11 | int max_sum = INT_MIN, sum = 0; 12 | for (const auto& i : nums) { 13 | sum += i; 14 | max_sum = max(max_sum, sum); 15 | sum = max(sum, 0); 16 | } 17 | return max_sum; 18 | } 19 | }; 20 | 21 | -------------------------------------------------------------------------------- /C++/update-bits.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(1) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | *@param n, m: Two integer 8 | *@param i, j: Two bit positions 9 | *return: An integer 10 | */ 11 | int updateBits(int n, int m, int i, int j) { 12 | int right_part = n & ((1 << i) - 1); 13 | // The behavior of right shift >= 32 is undefined in C++. 14 | int left_part = j >= 31 ? 0 : (n >> (j + 1)) << (j + 1); 15 | return left_part | (m << i) | right_part; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /C++/fibonacci.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution{ 5 | public: 6 | /** 7 | * @param n: an integer 8 | * @return an integer f(n) 9 | */ 10 | int fibonacci(int n) { 11 | if (n <= 1) { 12 | return n; 13 | } 14 | 15 | int n_i = 1, n_i_1 = 1, n_i_2 = 0; 16 | for (int i = 2; i < n; ++i) { 17 | n_i = n_i_1 + n_i_2; 18 | n_i_2 = n_i_1; 19 | n_i_1 = n_i; 20 | } 21 | 22 | return n_i; 23 | } 24 | }; 25 | 26 | -------------------------------------------------------------------------------- /C++/single-number-ii.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param A : An integer array 8 | * @return : An integer 9 | */ 10 | int singleNumberII(vector &A) { 11 | int one = 0, two = 0; 12 | 13 | for (const auto& i : A) { 14 | int new_one = (~i & one) | (i & ~one & ~two); 15 | int new_two = (~i & two) | (i & one); 16 | one = new_one, two = new_two; 17 | } 18 | 19 | return one; 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /C++/wiggle-sort.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param nums a list of integer 8 | * @return void 9 | */ 10 | void wiggleSort(vector& nums) { 11 | for (int i = 1; i < nums.size(); ++i) { 12 | if (((i % 2) && nums[i] < nums[i - 1]) || 13 | (!(i % 2) && nums[i] > nums[i - 1])) { 14 | // Swap unordered elements. 15 | swap(nums[i], nums[i - 1]); 16 | } 17 | } 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /C++/minimum-subarray.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param nums: a list of integers 8 | * @return: A integer denote the sum of minimum subarray 9 | */ 10 | int minSubArray(vector nums) { 11 | int min_sum = INT_MAX, sum = 0; 12 | for (auto& i : nums) { 13 | sum += i; 14 | min_sum = min(min_sum, sum); 15 | if (sum > 0) { 16 | sum = 0; 17 | } 18 | } 19 | return min_sum; 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /C++/partition-array.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | int partitionArray(vector &nums, int k) { 7 | int left = 0, right = nums.size() - 1; 8 | 9 | while (left <= right) { 10 | if (nums[left] < k) { 11 | ++left; 12 | } else if (nums[right] >= k) { 13 | --right; 14 | } else { 15 | swap(nums[left++], nums[right--]); 16 | } 17 | } 18 | 19 | return left; 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /C++/sort-letters-by-case.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Spacee: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param chars: The letters array you should sort. 8 | */ 9 | void sortLetters(string &letters) { 10 | int left = 0, right = letters.size() - 1; 11 | 12 | while (left < right) { 13 | if (isupper(letters[left])) { 14 | swap(letters[left], letters[right]); 15 | --right; 16 | } else { 17 | ++left; 18 | } 19 | } 20 | } 21 | }; 22 | 23 | -------------------------------------------------------------------------------- /C++/hash-function.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param key: A String you should hash 8 | * @param HASH_SIZE: An integer 9 | * @return an integer 10 | */ 11 | int hashCode(string key,int HASH_SIZE) { 12 | long long value = 0L; 13 | for (const auto& c : key) { 14 | value = value * 33L % HASH_SIZE; 15 | value = (value + static_cast(c) % HASH_SIZE) % HASH_SIZE; 16 | } 17 | return static_cast(value); 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /C++/length-of-last-word.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param s A string 8 | * @return the length of last word 9 | */ 10 | int lengthOfLastWord(string& s) { 11 | int counter = 0; 12 | for (int i = s.length() - 1; i >= 0; --i) { 13 | if(s[i] == ' ') { 14 | if (counter > 0) { 15 | break; 16 | } 17 | } else { 18 | ++counter; 19 | } 20 | } 21 | return counter; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /C++/rotate-string.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * param A: A string 8 | * param offset: Rotate string with offset. 9 | * return: Rotated string. 10 | */ 11 | string rotateString(string A, int offset) { 12 | if (!A.empty()) { 13 | offset %= A.length(); 14 | reverse(A.begin(), A.begin() + A.length() - offset); 15 | reverse(A.begin() + A.length() - offset, A.end()); 16 | reverse(A.begin(), A.end()); 17 | } 18 | return A; 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /C++/remove-element.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | *@param A: A list of integers 8 | *@param elem: An integer 9 | *@return: The new length after remove 10 | */ 11 | int removeElement(vector &A, int elem) { 12 | int left = 0; 13 | int right = A.size(); 14 | while (left < right) { 15 | if (A[left] != elem) { 16 | ++left; 17 | } else { 18 | swap(A[left], A[--right]); 19 | } 20 | } 21 | return left; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /C++/left-pad.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(p + n), p is the number of padChars 2 | // Space: O(1) 3 | 4 | class StringUtils { 5 | public: 6 | /** 7 | * @param originalStr the string we want to append to 8 | * @param size the target length of the string 9 | * @param padChar the character to pad to the left side of the string 10 | * @return a string 11 | */ 12 | static string leftPad(string& originalStr, int size, char padChar=' ') { 13 | 14 | return string(max(0, size - static_cast(originalStr.length())), 15 | padChar).append(originalStr); 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /C++/reverse-integer.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(logn) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param n the integer to be reversed 8 | * @return the reversed integer 9 | */ 10 | int reverseInteger(int n) { 11 | int result = 0; 12 | while (n) { 13 | auto prev = result; 14 | result *= 10; 15 | result += n % 10; 16 | if (result / 10 != prev) { 17 | result = 0; 18 | break; 19 | } 20 | n /= 10; 21 | } 22 | return result; 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /C++/partition-array-by-odd-and-even.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param nums: a vector of integers 8 | * @return: nothing 9 | */ 10 | void partitionArray(vector &nums) { 11 | for (int left = 0, right = nums.size() - 1; left <= right;) { 12 | if (nums[left] % 2 == 1) { 13 | ++left; 14 | } else if (nums[right] % 2 == 0) { 15 | --right; 16 | } else { 17 | swap(nums[left++], nums[right--]); 18 | } 19 | } 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /C++/find-peak-element.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(logn) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param A: An integers array. 8 | * @return: return any of peek positions. 9 | */ 10 | int findPeak(vector A) { 11 | int left = 0, right = A.size() - 1; 12 | 13 | while (left < right) { 14 | const auto mid = left + (right - left) / 2; 15 | if (A[mid] > A[mid + 1]) { 16 | right = mid; 17 | } else { 18 | left = mid + 1; 19 | } 20 | } 21 | 22 | return left; 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /C++/singleton.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(1) 2 | // Space: O(1) 3 | 4 | // Thread-Safe, Lazy Initilization 5 | class Solution { 6 | public: 7 | /** 8 | * @return: The same instance of this class every time 9 | */ 10 | static Solution* getInstance() { 11 | // C++ 11 thread-safe local-static-initialization. (lazy initialization) 12 | static Solution *instance = new Solution(); 13 | 14 | return instance; 15 | } 16 | 17 | // Noncopyable. 18 | Solution(const Solution&) = delete; 19 | Solution& operator=(const Solution&) = delete; 20 | 21 | private: 22 | Solution() {} 23 | ~Solution() {} 24 | }; 25 | -------------------------------------------------------------------------------- /C++/majority-number.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param nums: A list of integers 8 | * @return: The majority number 9 | */ 10 | int majorityNumber(vector nums) { 11 | int ans = nums[0], cnt = 1; 12 | for (const auto& i : nums) { 13 | if (i == ans) { 14 | ++cnt; 15 | } else { 16 | --cnt; 17 | if (cnt == 0) { 18 | ans = i; 19 | cnt = 1; 20 | } 21 | } 22 | } 23 | return ans; 24 | } 25 | }; 26 | 27 | -------------------------------------------------------------------------------- /C++/subarray-sum.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | /** 4 | * @param nums: A list of integers 5 | * @return: A list of integers includes the index of the first number 6 | * and the index of the last number 7 | */ 8 | vector subarraySum(vector nums) { 9 | unordered_map table; 10 | table[0] = -1; 11 | for (int i = 0, sum = 0; i < nums.size(); ++i) { 12 | sum += nums[i]; 13 | if (!table.emplace(sum, i).second) { // Already exists. 14 | return {table[sum] + 1, i}; 15 | } 16 | } 17 | return {}; 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /C++/sort-colors.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | // Tri-Partition solution. 5 | class Solution{ 6 | public: 7 | /** 8 | * @param nums: A list of integer which is 0, 1 or 2 9 | * @return: nothing 10 | */ 11 | void sortColors(vector &nums) { 12 | const int target = 1; 13 | for (int i = 0, j = 0, n = nums.size() - 1; j <= n;) { 14 | if (nums[j] < target) { 15 | swap(nums[i++], nums[j++]); 16 | } else if (nums[j] > target) { 17 | swap(nums[j], nums[n--]); 18 | } else { 19 | ++j; 20 | } 21 | } 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /C++/backpack-vi.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n * t) 2 | // Space: O(t) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param nums an integer array and all positive numbers, no duplicates 8 | * @param target an integer 9 | * @return an integer 10 | */ 11 | int backPackVI(vector& nums, int target) { 12 | vector dp(target + 1); 13 | dp[0] = 1; 14 | for (int i = 1; i <= target; ++i) { 15 | for (const auto& num : nums) { 16 | if (i >= num) { 17 | dp[i] += dp[i - num]; 18 | } 19 | } 20 | } 21 | return dp.back(); 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /C++/single-number.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param A: Array of integers. 8 | * return: The single number. 9 | */ 10 | int singleNumber(vector &A) { 11 | return accumulate(A.cbegin(), A.cend(), 0, std::bit_xor()); 12 | } 13 | }; 14 | 15 | class Solution2 { 16 | public: 17 | /** 18 | * @param A: Array of integers. 19 | * return: The single number. 20 | */ 21 | int singleNumber(vector &A) { 22 | int single = 0; 23 | for (const auto& i : A) { 24 | single ^= i; 25 | } 26 | 27 | return single; 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /C++/plus-one.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param digits a number represented as an array of digits 8 | * @return the result 9 | */ 10 | vector plusOne(vector& digits) { 11 | vector result(digits.cbegin(), digits.cend()); 12 | int carry = 1; 13 | for (auto it = result.rbegin(); it != result.rend(); ++it) { 14 | *it += carry; 15 | carry = *it / 10; 16 | *it %= 10; 17 | } 18 | if (carry == 1) { 19 | result.emplace(result.begin(), carry); 20 | } 21 | return result; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /C++/remove-duplicates-from-sorted-array.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param A: a list of integers 8 | * @return : return an integer 9 | */ 10 | int removeDuplicates(vector &nums) { 11 | if (nums.empty()) { 12 | return 0; 13 | } 14 | 15 | int left = 0; 16 | int right = 1; 17 | 18 | while (right < nums.size()) { 19 | if (nums[left] != nums[right]) { 20 | ++left; 21 | nums[left] = nums[right]; 22 | } 23 | ++right; 24 | } 25 | 26 | return left + 1; 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /C++/maximum-depth-of-binary-tree.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(h) 3 | 4 | /** 5 | * Definition of TreeNode: 6 | * class TreeNode { 7 | * public: 8 | * int val; 9 | * TreeNode *left, *right; 10 | * TreeNode(int val) { 11 | * this->val = val; 12 | * this->left = this->right = NULL; 13 | * } 14 | * } 15 | */ 16 | class Solution { 17 | public: 18 | /** 19 | * @param root: The root of binary tree. 20 | * @return: An integer 21 | */ 22 | int maxDepth(TreeNode *root) { 23 | if (root == nullptr) { 24 | return 0; 25 | } 26 | return max(maxDepth(root->left), maxDepth(root->right)) + 1; 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /C++/maximum-product-subarray.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param nums: a vector of integers 8 | * @return: an integer 9 | */ 10 | int maxProduct(vector& nums) { 11 | int global_max = INT_MIN, local_max = 1, local_min = 1; 12 | 13 | for (const auto& n : nums) { 14 | int cur_max = local_max * n; 15 | int cur_min = local_min * n; 16 | local_max = max(n, max(cur_max, cur_min)); 17 | local_min = min(n, min(cur_max, cur_min)); 18 | global_max = max(global_max, local_max); 19 | } 20 | 21 | return global_max; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /C++/valid-palindrome.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param s A string 8 | * @return Whether the string is a valid palindrome 9 | */ 10 | bool isPalindrome(string& s) { 11 | int i = 0, j = s.size() - 1; 12 | while (i < j) { 13 | while (i < j && !isalnum(s[i])) { 14 | ++i; 15 | } 16 | while (i < j && !isalnum(s[j])) { 17 | --j; 18 | } 19 | if (tolower(s[i]) != tolower(s[j])) { 20 | return false; 21 | } 22 | ++i, --j; 23 | } 24 | return true; 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /C++/happy-number.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(k), where k is the steps to be happy number 2 | // Space: O(k) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param n an integer 8 | * @return true if this is a happy number or false 9 | */ 10 | bool isHappy(int n) { 11 | unordered_set visited; 12 | while (n != 1 && !visited.count(n)) { 13 | visited.emplace(n); 14 | n = nextNumber(n); 15 | } 16 | return n == 1; 17 | } 18 | 19 | int nextNumber(int n) { 20 | int sum = 0; 21 | while (n) { 22 | sum += pow(n % 10, 2); 23 | n /= 10; 24 | } 25 | return sum; 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /C++/string-permutation.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param A a string 8 | * @param B a string 9 | * @return a boolean 10 | */ 11 | bool stringPermutation(string& A, string& B) { 12 | if (A.length() != B.length()) { 13 | return false; 14 | } 15 | unordered_map words; 16 | for (const auto& c : A) { 17 | ++words[c]; 18 | } 19 | for (const auto& c : B) { 20 | if (words[c]) { 21 | --words[c]; 22 | } else { 23 | return false; 24 | } 25 | } 26 | return true; 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /C++/median.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param nums: A list of integers. 8 | * @return: An integer denotes the middle number of the array. 9 | */ 10 | int median(vector &nums) { 11 | auto target = nums.begin() + nums.size() / 2; 12 | nth_element(nums.begin(), target, nums.end()); 13 | if (nums.size() % 2 == 1) { // nums has odd number of elements. 14 | return *target; 15 | } else { // nums has even number of elements. 16 | int x = *target; 17 | nth_element(nums.begin(), target - 1, nums.end()); 18 | return *(target - 1); 19 | } 20 | } 21 | }; 22 | 23 | -------------------------------------------------------------------------------- /C++/implement-queue-by-two-stacks.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(1), amortized 2 | // Space: O(n) 3 | 4 | class Queue { 5 | public: 6 | stack stack1; 7 | stack stack2; 8 | 9 | Queue() { 10 | // do intialization if necessary 11 | } 12 | 13 | void push(int element) { 14 | stack1.emplace(element); 15 | } 16 | 17 | int pop() { 18 | int element = top(); 19 | stack2.pop(); 20 | return element; 21 | } 22 | 23 | int top() { 24 | if (stack2.empty()) { 25 | while (!stack1.empty()) { 26 | stack2.emplace(stack1.top()); 27 | stack1.pop(); 28 | } 29 | } 30 | return stack2.top(); 31 | } 32 | }; 33 | 34 | -------------------------------------------------------------------------------- /C++/container-with-most-water.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param heights: a vector of integers 8 | * @return: an integer 9 | */ 10 | int maxArea(vector &heights) { 11 | int i = 0, j = heights.size() - 1, max_area = 0; 12 | while (i < j) { 13 | max_area = max(max_area, min(heights[i], heights[j]) * (j - i)); 14 | if (heights[i] > heights[j]) { 15 | --j; 16 | } else if (heights[i] < heights[j]) { 17 | ++i; 18 | } else { // heights[i] == heights[j]. 19 | ++i, --j; 20 | } 21 | } 22 | return max_area; 23 | } 24 | }; 25 | 26 | -------------------------------------------------------------------------------- /C++/fizz-buzz.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * param n: As description. 8 | * return: A list of strings. 9 | */ 10 | vector fizzBuzz(int n) { 11 | vector result; 12 | 13 | for (int i = 1; i <= n; ++i) { 14 | if (i % 15 == 0) { 15 | result.emplace_back("fizz buzz"); 16 | } else if (i % 5 == 0) { 17 | result.emplace_back("buzz"); 18 | } else if (i % 3 == 0) { 19 | result.emplace_back("fizz"); 20 | } else { 21 | result.emplace_back(to_string(i)); 22 | } 23 | } 24 | 25 | return result; 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /Python/cosine-similarity.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | 4 | from math import sqrt 5 | 6 | class Solution: 7 | """ 8 | @param A: An integer array. 9 | @param B: An integer array. 10 | @return: Cosine similarity. 11 | """ 12 | def cosineSimilarity(self, A, B): 13 | invalid = 2.0 14 | if len(A) != len(B): 15 | return invalid 16 | A_dot_B, A_dot_A, B_dot_B = 0.0, 0.0, 0.0 17 | for i in xrange(len(A)): 18 | A_dot_B += A[i] * B[i] 19 | A_dot_A += A[i] * A[i] 20 | B_dot_B += B[i] * B[i] 21 | return A_dot_B / sqrt(A_dot_A) / sqrt(B_dot_B) if A_dot_A and B_dot_B \ 22 | else invalid 23 | -------------------------------------------------------------------------------- /C++/2-sum.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(n) 3 | 4 | class Solution { 5 | public: 6 | /* 7 | * @param numbers : An array of Integer 8 | * @param target : target = numbers[index1] + numbers[index2] 9 | * @return : [index1+1, index2+1] (index1 < index2) 10 | */ 11 | vector twoSum(vector &nums, int target) { 12 | unordered_map hash; 13 | 14 | for (int i = 0; i < nums.size(); ++i) { 15 | // Check if "target - nums[i]" exists or not 16 | if (hash.find(target - nums[i]) != hash.end()) { 17 | return {hash[target - nums[i]] + 1, i + 1}; 18 | } 19 | hash[nums[i]] = i; 20 | } 21 | 22 | return {}; 23 | } 24 | }; 25 | 26 | -------------------------------------------------------------------------------- /C++/two-strings-are-anagrams.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param s: The first string 8 | * @param b: The second string 9 | * @return true or false 10 | */ 11 | bool anagram(string s, string t) { 12 | if (s.length() != t.length()) { 13 | return false; 14 | } 15 | 16 | unordered_map count; 17 | 18 | for (const auto& c: s) { 19 | ++count[tolower(c)]; 20 | } 21 | 22 | for (const auto& c: t) { 23 | --count[tolower(c)]; 24 | if (count[tolower(c)] < 0) { 25 | return false; 26 | } 27 | } 28 | 29 | return true; 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /C++/paint-fence.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | // DP with rolling window. 5 | class Solution { 6 | public: 7 | /** 8 | * @param n non-negative integer, n posts 9 | * @param k non-negative integer, k colors 10 | * @return an integer, the total number of ways 11 | */ 12 | int numWays(int n, int k) { 13 | if (n == 0) { 14 | return 0; 15 | } else if (n == 1) { 16 | return k; 17 | } 18 | vector ways(3); 19 | ways[0] = k; 20 | ways[1] = (k - 1) * ways[0] + k; 21 | for (int i = 2; i < n; ++i) { 22 | ways[i % 3] = (k - 1) * (ways[(i - 1) % 3] + ways[(i - 2) % 3]); 23 | } 24 | return ways[(n - 1) % 3]; 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /C++/count-and-say.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n * 2^n) 2 | // Space: O(2^n) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param n the nth 8 | * @return the nth sequence 9 | */ 10 | string countAndSay(int n) { 11 | string seq{"1"}; 12 | for (int i = 0; i < n - 1; ++i) { 13 | seq = getNext(seq); 14 | } 15 | return seq; 16 | } 17 | 18 | string getNext(const string& seq) { 19 | stringstream next_seq; 20 | for (int i = 0; i < seq.length(); ++i) { 21 | int cnt = 1; 22 | while (i < seq.length() - 1 && seq[i] == seq[i + 1]) { 23 | ++cnt, ++i; 24 | } 25 | next_seq << cnt << seq[i]; 26 | } 27 | return next_seq.str(); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /Python/single-number-iii.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(1) 3 | # 4 | # Given 2*n + 2 numbers, every numbers occurs twice except two, find them. 5 | # 6 | # Example 7 | # Given [1,2,2,3,4,4,5,3] return 1 and 5 8 | # 9 | # Challenge 10 | # O(n) time, O(1) extra space. 11 | # 12 | 13 | class Solution: 14 | """ 15 | @param A : An integer array 16 | @return : Two integer 17 | """ 18 | def singleNumberIII(self, A): 19 | # write your code here 20 | x_xor_y = 0 21 | for i in A: 22 | x_xor_y ^= i 23 | bit = x_xor_y & ~(x_xor_y - 1) 24 | 25 | x = 0 26 | A_x = (i for i in A if i & bit) 27 | for i in A_x: 28 | x ^= i 29 | 30 | return [x, x_xor_y ^ x] 31 | -------------------------------------------------------------------------------- /C++/palindrome-partitioning-ii.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n^2) 2 | // Space: O(n) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param s a string 8 | * @return an integer 9 | */ 10 | int minCut(string s) { 11 | vector> is_palindrome(s.size(), deque(s.size(), false)); 12 | vector T(s.size() + 1); 13 | iota(T.rbegin(), T.rend(), -1); 14 | for (int i = s.size() - 1; i >= 0; --i) { 15 | for (int j = i; j < s.size(); ++j) { 16 | if (s[i] == s[j] && (j - i < 2 || is_palindrome[i + 1][j - 1])) { 17 | is_palindrome[i][j] = true; 18 | T[i] = min(T[i], 1 + T[j + 1]); 19 | } 20 | } 21 | } 22 | return T[0]; 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /C++/delete-node-in-the-middle-of-singly-linked-list.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(1) 2 | // Space: O(1) 3 | 4 | /** 5 | * Definition of ListNode 6 | * class ListNode { 7 | * public: 8 | * int val; 9 | * ListNode *next; 10 | * ListNode(int val) { 11 | * this->val = val; 12 | * this->next = NULL; 13 | * } 14 | * } 15 | */ 16 | class Solution { 17 | public: 18 | /** 19 | * @param node: a node in the list should be deleted 20 | * @return: nothing 21 | */ 22 | void deleteNode(ListNode *node) { 23 | if (!node || !node->next) { 24 | return; 25 | } 26 | auto node_to_delete = node->next; 27 | node->val = node->next->val; 28 | node->next = node->next->next; 29 | delete node_to_delete; 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /C++/longest-words.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(n) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param dictionary: a vector of strings 8 | * @return: a vector of strings 9 | */ 10 | vector longestWords(vector &dictionary) { 11 | vector longest_words; 12 | for (const auto& word : dictionary) { 13 | if (!longest_words.empty() && 14 | word.length() > longest_words[0].length()) { 15 | longest_words = move(vector{word}); 16 | } else if (longest_words.empty() || 17 | word.length() == longest_words[0].length()) { 18 | longest_words.emplace_back(word); 19 | } 20 | } 21 | return longest_words; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /C++/a-b-problem.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(logn) = O(32) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /* 7 | * @param a: The first integer 8 | * @param b: The second integer 9 | * @return: The sum of a and b 10 | */ 11 | int aplusb(int a, int b) { 12 | while (b != 0) { 13 | int carry = a & b; 14 | a ^= b; 15 | b = carry << 1; 16 | } 17 | return a; 18 | } 19 | }; 20 | 21 | class Solution2 { 22 | public: 23 | /* 24 | * @param a: The first integer 25 | * @param b: The second integer 26 | * @return: The sum of a and b 27 | */ 28 | int aplusb(int a, int b) { 29 | if (b == 0) { 30 | return a; 31 | } 32 | return aplusb(a ^ b, (a & b) << 1); 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /C++/candy.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(n) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param ratings Children's ratings 8 | * @return the minimum candies you must give 9 | */ 10 | int candy(vector& ratings) { 11 | vector candies(ratings.size(), 1); 12 | for (int i = 1; i < ratings.size(); ++i) { 13 | if (ratings[i] > ratings[i - 1]) { 14 | candies[i] = candies[i - 1] + 1; 15 | } 16 | } 17 | for (int i = ratings.size() - 2; i >= 0; --i) { 18 | if (ratings[i] > ratings[i + 1] && candies[i] <= candies[i + 1]) { 19 | candies[i] = candies[i + 1] + 1; 20 | } 21 | } 22 | return accumulate(candies.cbegin(), candies.cend(), 0); 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /C++/reorder-array-to-construct-the-minimum-number.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(nlogn) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param nums n non-negative integer array 8 | * @return a string 9 | */ 10 | string minNumber(vector& nums) { 11 | sort(nums.begin(), nums.end(), [](const int &i, const int &j) { 12 | return to_string(i) + to_string(j) < to_string(j) + to_string(i); 13 | }); 14 | 15 | string min_num; 16 | for (const auto& i : nums) { 17 | min_num.append(to_string(i)); 18 | } 19 | 20 | int i = 0; 21 | while (i + 1 < min_num.length() && min_num[i] == '0') { 22 | ++i; 23 | } 24 | 25 | return min_num.empty() ? "0" : min_num.substr(i); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /C++/remove-duplicates-from-sorted-array-ii.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param A: a list of integers 8 | * @return : return an integer 9 | */ 10 | int removeDuplicates(vector &nums) { 11 | if (nums.empty()) { 12 | return 0; 13 | } 14 | 15 | const int k = 2; // At most k duplicated. 16 | 17 | int left = 0; 18 | int right = 1; 19 | 20 | while (right < nums.size()) { 21 | if (nums[left] != nums[right] || 22 | (left - k + 1 < 0 || nums[left] != nums[left - k + 1])) { 23 | ++left; 24 | nums[left] = nums[right]; 25 | } 26 | ++right; 27 | } 28 | 29 | return left + 1; 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /C++/cosine-similarity.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param A: An integer array. 8 | * @param B: An integer array. 9 | * @return: Cosine similarity. 10 | */ 11 | double cosineSimilarity(vector A, vector B) { 12 | const double invalid = 2.0; 13 | if (A.size() != B.size()) { 14 | return invalid; 15 | } 16 | 17 | double A_dot_B = 0.0, A_dot_A = 0.0, B_dot_B = 0.0; 18 | for (int i = 0; i < A.size(); ++i) { 19 | A_dot_B += A[i] * B[i]; 20 | A_dot_A += A[i] * A[i]; 21 | B_dot_B += B[i] * B[i]; 22 | } 23 | return A_dot_A && B_dot_B ? 24 | A_dot_B / sqrt(A_dot_A) / sqrt(B_dot_B) : 25 | invalid; 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /C++/find-minimum-in-rotated-sorted-array-ii.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(logn) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param num: a rotated sorted array 8 | * @return: the minimum number in the array 9 | */ 10 | int findMin(vector &num) { 11 | int left = 0; 12 | int right = num.size() - 1; 13 | 14 | // Find min left s.t. num[left] < num[left']. 15 | while (left < right && num[left] >= num[right]) { 16 | int mid = left + (right - left) / 2; 17 | if (num[mid] < num[left]) { 18 | right = mid; 19 | } else if (num[mid] > num[left]) { 20 | left = mid + 1; 21 | } else { 22 | ++left; 23 | } 24 | } 25 | 26 | return num[left]; 27 | } 28 | }; 29 | 30 | -------------------------------------------------------------------------------- /C++/largest-number.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(nlogn) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | *@param num: A list of non negative integers 8 | *@return: A string 9 | */ 10 | string largestNumber(vector &num) { 11 | // sort numbers 12 | sort(num.begin(), num.end(), [](const int &i, const int &j) { 13 | return to_string(i) + to_string(j) > to_string(j) + to_string(i); 14 | }); 15 | 16 | // combine the numbers 17 | string max_num; 18 | for (const auto& i : num) { 19 | max_num.append(to_string(i)); 20 | } 21 | 22 | // special case: start with zero (e.g. [0, 0]) 23 | if (!max_num.empty() && max_num[0] == '0') { 24 | return "0"; 25 | } 26 | 27 | return max_num; 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /C++/clone-binary-tree.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(h) 3 | 4 | /** 5 | * Definition of TreeNode: 6 | * class TreeNode { 7 | * public: 8 | * int val; 9 | * TreeNode *left, *right; 10 | * TreeNode(int val) { 11 | * this->val = val; 12 | * this->left = this->right = NULL; 13 | * } 14 | * } 15 | */ 16 | class Solution { 17 | public: 18 | /** 19 | * @param root: The root of binary tree 20 | * @return root of new tree 21 | */ 22 | TreeNode* cloneTree(TreeNode *root) { 23 | if (root == nullptr) { 24 | return nullptr; 25 | } 26 | 27 | auto clone_root = new TreeNode(root->val); 28 | clone_root->left = cloneTree(root->left); 29 | clone_root->right = cloneTree(root->right); 30 | 31 | return clone_root; 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /C++/reverse-linked-list.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | /** 5 | * Definition of ListNode 6 | * 7 | * class ListNode { 8 | * public: 9 | * int val; 10 | * ListNode *next; 11 | * 12 | * ListNode(int val) { 13 | * this->val = val; 14 | * this->next = NULL; 15 | * } 16 | * } 17 | */ 18 | class Solution { 19 | public: 20 | /** 21 | * @param head: The first node of linked list. 22 | * @return: The new head of reversed linked list. 23 | */ 24 | ListNode *reverse(ListNode *head) { 25 | ListNode dummy{0}; 26 | 27 | while (head != nullptr) { 28 | auto tmp = head->next; 29 | head->next = dummy.next; 30 | dummy.next = head; 31 | head = tmp; 32 | } 33 | 34 | return dummy.next; 35 | } 36 | }; 37 | 38 | -------------------------------------------------------------------------------- /C++/integer-to-roman.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param n The integer 8 | * @return Roman representation 9 | */ 10 | string intToRoman(int n) { 11 | const vector nums{1000, 900, 500, 400, 100, 90, 12 | 50, 40, 10, 9, 5, 4, 1}; 13 | const vector romans{"M", "CM", "D", "CD", "C", "XC", "L", 14 | "XL", "X", "IX", "V", "IV", "I"}; 15 | 16 | string result; 17 | int i = 0; 18 | while (n > 0) { 19 | int times = n / nums[i]; 20 | while (times--) { 21 | n -= nums[i]; 22 | result.append(romans[i]); 23 | } 24 | ++i; 25 | } 26 | return result; 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /C++/linked-list-cycle.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | /** 5 | * Definition of ListNode 6 | * class ListNode { 7 | * public: 8 | * int val; 9 | * ListNode *next; 10 | * ListNode(int val) { 11 | * this->val = val; 12 | * this->next = NULL; 13 | * } 14 | * } 15 | */ 16 | class Solution { 17 | public: 18 | /** 19 | * @param head: The first node of linked list. 20 | * @return: True if it has a cycle, or false 21 | */ 22 | bool hasCycle(ListNode *head) { 23 | auto slow = head, fast = head; 24 | 25 | while (fast && fast->next) { 26 | slow = slow->next, fast = fast->next->next; 27 | if (slow == fast) { // There is a cycle. 28 | return true; 29 | } 30 | } 31 | return false; // No cycle. 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /C++/roman-to-integer.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param s Roman representation 8 | * @return an integer 9 | */ 10 | int romanToInt(string& s) { 11 | unordered_map numeral_map = {{'I', 1}, {'V', 5}, {'X', 10}, 12 | {'L', 50}, {'C', 100}, {'D', 500}, 13 | {'M', 1000}}; 14 | int decimal = 0; 15 | for (int i = 0; i < s.length(); ++i) { 16 | if (i > 0 && numeral_map[s[i]] > numeral_map[s[i - 1]]) { 17 | decimal += numeral_map[s[i]] - 2 * numeral_map[s[i - 1]]; 18 | } else { 19 | decimal += numeral_map[s[i]]; 20 | } 21 | } 22 | return decimal; 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /C++/merge-sorted-array.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(m + n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param A: sorted integer array A which has m elements, 8 | * but size of A is m+n 9 | * @param B: sorted integer array B which has n elements 10 | * @return: void 11 | */ 12 | void mergeSortedArray(int A[], int m, int B[], int n) { 13 | int i = m + n; 14 | while (m > 0 && n > 0) { 15 | if (A[m - 1] > B[n - 1]) { 16 | A[i - 1] = A[m - 1]; 17 | --m; 18 | } else { 19 | A[i - 1] = B[n - 1]; 20 | --n; 21 | } 22 | --i; 23 | } 24 | 25 | while (n > 0) { 26 | A[i - 1] = B[n - 1]; 27 | --n; 28 | --i; 29 | } 30 | } 31 | }; 32 | 33 | -------------------------------------------------------------------------------- /C++/anagrams.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n * klogk), k is max length of strings 2 | // Space: O(m), m is number of anagram groups 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param strs: A list of strings 8 | * @return: A list of strings 9 | */ 10 | vector anagrams(vector &strs) { 11 | unordered_map table; 12 | 13 | for (auto str : strs) { 14 | sort(str.begin(), str.end()); 15 | ++table[str]; 16 | } 17 | 18 | vector anagrams; 19 | for (const auto& str : strs) { 20 | string sorted_str(str); 21 | sort(sorted_str.begin(), sorted_str.end()); 22 | if (table[sorted_str] >= 2) { 23 | anagrams.emplace_back(str); 24 | } 25 | } 26 | 27 | return anagrams; 28 | } 29 | }; 30 | 31 | -------------------------------------------------------------------------------- /C++/permutation-index.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n^2) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param A an integer array 8 | * @return a long integer 9 | */ 10 | long long permutationIndex(vector& A) { 11 | long long index = 1; 12 | // Position 1 is paired with factor 0 and so is skipped. 13 | int position = 2; 14 | long long factor = 1; 15 | for (int i = static_cast(A.size()) - 2; i >= 0; --i) { 16 | int successors = 0; 17 | for (int j = i + 1; j < A.size(); ++j) { 18 | if (A[i] > A[j]) { 19 | ++successors; 20 | } 21 | } 22 | index += successors * factor; 23 | factor *= position; 24 | ++position; 25 | } 26 | return index; 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /C++/identical-binary-tree.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(h) 3 | 4 | /** 5 | * Definition of TreeNode: 6 | * class TreeNode { 7 | * public: 8 | * int val; 9 | * TreeNode *left, *right; 10 | * TreeNode(int val) { 11 | * this->val = val; 12 | * this->left = this->right = NULL; 13 | * } 14 | * } 15 | */ 16 | class Solution { 17 | public: 18 | /** 19 | * @aaram a, b, the root of binary trees. 20 | * @return true if they are identical, or false. 21 | */ 22 | bool isIdentical(TreeNode* a, TreeNode* b) { 23 | if (!a && !b) { 24 | return true; 25 | } 26 | if (a && b) { 27 | return a->val == b->val && 28 | isIdentical(a->left, b->left) && 29 | isIdentical(a->right, b->right); 30 | } 31 | return false; 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /C++/jump-game-ii.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param A: A list of lists of integers 8 | * @return: An integer 9 | */ 10 | int jump(vector A) { 11 | int jump_count = 0; 12 | int reachable = 0; 13 | int curr_reachable = 0; 14 | for (int i = 0; i < A.size(); ++i) { 15 | if (i > reachable) { 16 | return -1; 17 | } 18 | if (i > curr_reachable) { 19 | // current jumps are not enough, 20 | // jump one more step, which enlarges curr_reachable to reachable. 21 | curr_reachable = reachable; 22 | ++jump_count; 23 | } 24 | reachable = max(reachable, i + A[i]); 25 | } 26 | 27 | return jump_count; 28 | } 29 | }; 30 | 31 | 32 | -------------------------------------------------------------------------------- /C++/remove-duplicates-from-sorted-list.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | /** 5 | * Definition of ListNode 6 | * class ListNode { 7 | * public: 8 | * int val; 9 | * ListNode *next; 10 | * ListNode(int val) { 11 | * this->val = val; 12 | * this->next = NULL; 13 | * } 14 | * } 15 | */ 16 | class Solution { 17 | public: 18 | /** 19 | * @param head: The first node of linked list. 20 | * @return: head node 21 | */ 22 | ListNode *deleteDuplicates(ListNode *head) { 23 | auto iter = head; 24 | while (iter) { 25 | auto runner = iter->next; 26 | while (runner && runner->val == iter->val) { 27 | runner = runner->next; 28 | } 29 | iter->next = runner; 30 | iter = runner; 31 | } 32 | return head; 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /C++/sliding-window-maximum.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(k) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param nums: A list of integers. 8 | * @return: The maximum number inside the window at each moving. 9 | */ 10 | vector maxSlidingWindow(vector &nums, int k) { 11 | deque dq; 12 | vector max_numbers; 13 | 14 | for (int i = 0; i < nums.size(); ++i) { 15 | while ((!dq.empty() && nums[i] > nums[dq.back()])) { 16 | dq.pop_back(); 17 | } 18 | dq.emplace_back(i); 19 | if (i >= k && dq.front() == i - k) { 20 | dq.pop_front(); 21 | } 22 | if (i >= k - 1) { 23 | max_numbers.emplace_back(nums[dq.front()]); 24 | } 25 | } 26 | 27 | return max_numbers; 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /C++/house-robber.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param A: An array of non-negative integers. 8 | * return: The maximum amount of money you can rob tonight 9 | */ 10 | long long houseRobber(vector nums) { 11 | if (nums.size() == 0) { 12 | return 0; 13 | } 14 | if (nums.size() == 1) { 15 | return nums[0]; 16 | } 17 | 18 | return robRange(nums, 0, nums.size()); 19 | 20 | } 21 | 22 | long long robRange(const vector& nums, const int start, const int end) { 23 | long long num_i = nums[start], num_i_1 = 0, num_i_2 = 0; 24 | for (int i = start + 1; i < end; ++i) { 25 | num_i_2 = num_i_1; 26 | num_i_1 = num_i; 27 | num_i = max(nums[i] + num_i_2, num_i_1); 28 | } 29 | return num_i; 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /C++/decode-ways.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param s a string, encoded message 8 | * @return an integer, the number of ways decoding 9 | */ 10 | int numDecodings(string& s) { 11 | if (s.empty()) { 12 | return 0; 13 | } 14 | 15 | int prev = 0; // f[n - 2] 16 | int cur = 1; // f[n - 1] 17 | 18 | for (int i = 0; i < s.length(); ++i) { 19 | if (s[i] == '0') { 20 | cur = 0; // f[n - 1] = 0 21 | } 22 | if (i == 0 || 23 | !(s[i - 1] == '1' || (s[i - 1] == '2' && s[i] <= '6'))) { 24 | prev = 0; // f[n - 2] = 0 25 | } 26 | 27 | int tmp = cur; 28 | cur += prev; // f[n] = f[n - 1] + f[n - 2] 29 | prev = tmp; 30 | } 31 | 32 | return cur; 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /C++/remove-linked-list-elements.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode(int x) : val(x), next(NULL) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | /** 15 | * @param head a ListNode 16 | * @param val an integer 17 | * @return a ListNode 18 | */ 19 | ListNode *removeElements(ListNode *head, int val) { 20 | ListNode dummy{0}; 21 | dummy.next = head; 22 | auto prev = &dummy, curr = dummy.next; 23 | 24 | while (curr) { 25 | if (curr->val == val) { 26 | prev->next = curr->next; 27 | delete curr; 28 | } else { 29 | prev = curr; 30 | } 31 | curr = curr->next; 32 | } 33 | return dummy.next; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /C++/minimum-depth-of-binary-tree.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(h) 3 | 4 | /** 5 | * Definition of TreeNode: 6 | * class TreeNode { 7 | * public: 8 | * int val; 9 | * TreeNode *left, *right; 10 | * TreeNode(int val) { 11 | * this->val = val; 12 | * this->left = this->right = NULL; 13 | * } 14 | * } 15 | */ 16 | class Solution { 17 | public: 18 | /** 19 | * @param root: The root of binary tree. 20 | * @return: An integer 21 | */ 22 | int minDepth(TreeNode *root) { 23 | if (root == nullptr) { 24 | return 0; 25 | } 26 | 27 | // Both children exist. 28 | if (root->left != nullptr && root->right != nullptr) { 29 | return 1 + min(minDepth(root->left), minDepth(root->right)); 30 | } 31 | else { 32 | return 1 + max(minDepth(root->left), minDepth(root->right)); 33 | } 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /C++/toy-factory.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(1) 2 | // Space: O(1) 3 | 4 | /** 5 | * Your object will be instantiated and called as such: 6 | * ToyFactory* tf = new ToyFactory(); 7 | * Toy* toy = tf->getToy(type); 8 | * toy->talk(); 9 | */ 10 | class Toy { 11 | public: 12 | virtual void talk() const=0; 13 | }; 14 | 15 | class Dog: public Toy { 16 | public: 17 | virtual void talk() const { 18 | cout << "Wow" << endl; 19 | } 20 | }; 21 | 22 | class Cat: public Toy { 23 | public: 24 | virtual void talk() const { 25 | cout << "Meow" << endl; 26 | } 27 | }; 28 | 29 | class ToyFactory { 30 | public: 31 | /** 32 | * @param type a string 33 | * @return Get object of the type 34 | */ 35 | Toy* getToy(string& type) { 36 | if (type == "Dog") { 37 | return new Dog(); 38 | } else if (type == "Cat") { 39 | return new Cat(); 40 | } 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /C++/add-binary.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param a a number 8 | * @param b a number 9 | * @return the result 10 | */ 11 | string addBinary(string& a, string& b) { 12 | string result; 13 | int result_length = max(a.length(), b.length()) ; 14 | 15 | int carry = 0; 16 | for (int i = 0; i < result_length; ++i) { 17 | int a_bit_i = i < a.length() ? a[a.length() - 1 - i] - '0' : 0; 18 | int b_bit_i = i < b.length() ? b[b.length() - 1 - i] - '0' : 0; 19 | int sum = carry + a_bit_i + b_bit_i; 20 | carry = sum / 2; 21 | sum %= 2; 22 | result.push_back('0' + sum); 23 | } 24 | if (carry) { 25 | result.push_back('0' + carry); 26 | } 27 | reverse(result.begin(), result.end()); 28 | 29 | return result; 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /C++/longest-substring-with-at-most-k-distinct-characters.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(n) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param s : A string 8 | * @return : The length of the longest substring 9 | * that contains at most k distinct characters. 10 | */ 11 | int lengthOfLongestSubstringKDistinct(string s, int k) { 12 | unordered_map distinct; 13 | 14 | int start = 0; 15 | int max_len = 0; 16 | for (int i = 0; i < s.length(); ++i) { 17 | ++distinct[s[i]]; 18 | while (distinct.size() > k) { 19 | --distinct[s[start]]; 20 | if (distinct[s[start]] == 0) { 21 | distinct.erase(s[start]); 22 | } 23 | ++start; 24 | } 25 | max_len = max(max_len, i - start + 1); 26 | } 27 | 28 | return max_len; 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /C++/word-break.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n * l^2), l is the max length of the words. 2 | // Space: O(n) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param s: A string s 8 | * @param dict: A dictionary of words dict 9 | */ 10 | bool wordBreak(string s, unordered_set &dict) { 11 | const int n = s.length(); 12 | 13 | size_t max_len = 0; 14 | for (const auto& str: dict) { 15 | max_len = max(max_len, str.length()); 16 | } 17 | 18 | vector canBreak(n + 1, false); 19 | canBreak[0] = true; 20 | for (int i = 1; i <= n; ++i) { 21 | for (int l = 1; l <= max_len && i - l >= 0; ++l) { 22 | if (canBreak[i - l] && dict.count(s.substr(i - l, l))) { 23 | canBreak[i] = true; 24 | break; 25 | } 26 | } 27 | } 28 | 29 | return canBreak[n]; 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /C++/swap-nodes-in-pairs.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode(int x) : val(x), next(NULL) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | /** 15 | * @param head a ListNode 16 | * @return a ListNode 17 | */ 18 | ListNode* swapPairs(ListNode* head) { 19 | ListNode dummy{0}; 20 | dummy.next = head; 21 | auto curr = &dummy; 22 | 23 | while (curr->next && curr->next->next) { 24 | auto next_one = curr->next; 25 | auto next_two = next_one->next; 26 | auto next_three = next_two->next; 27 | curr->next = next_two; 28 | next_two->next = next_one; 29 | next_one->next = next_three; 30 | curr = next_one; 31 | } 32 | 33 | return dummy.next; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /C++/recover-rotated-sorted-array.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | void recoverRotatedSortedArray(vector &nums) { 7 | int i = findMinPoint(nums); 8 | reverse(nums.begin(), nums.begin() + i); 9 | reverse(nums.begin() + i, nums.end()); 10 | reverse(nums.begin(), nums.end()); 11 | } 12 | 13 | 14 | int findMinPoint(vector &num) { 15 | int left = 0; 16 | int right = num.size() - 1; 17 | 18 | // Find min left s.t. num[left] > num[left + 1]. 19 | while (left < right && num[left] >= num[right]) { 20 | int mid = left + (right - left) / 2; 21 | if (num[mid] < num[left]) { 22 | right = mid; 23 | } else if (num[mid] > num[left]) { 24 | left = mid + 1; 25 | } else { 26 | ++left; 27 | } 28 | } 29 | 30 | return left; 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /C++/continuous-subarray-sum.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param A an integer array 8 | * @return A list of integers includes the index of 9 | * the first number and the index of the last number 10 | */ 11 | vector continuousSubarraySum(vector& A) { 12 | if (A.empty()) { 13 | return {-1, -1}; 14 | } 15 | 16 | int curr_sum = A[0]; 17 | int max_sum = curr_sum; 18 | vector max_i_j{0, 0}; 19 | for (int i = 0, j = 1; j < A.size(); ++j) { 20 | if (curr_sum < 0) { 21 | i = j; 22 | curr_sum = 0; 23 | } 24 | 25 | curr_sum += A[j]; 26 | if (curr_sum > max_sum) { 27 | max_sum = curr_sum; 28 | max_i_j[0] = i, max_i_j[1] = j; 29 | } 30 | } 31 | 32 | return max_i_j; 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /C++/reverse-words-in-a-string.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param s : A string 8 | * @return : A string 9 | */ 10 | string reverseWords(string s) { 11 | // Reverse the whole string first. 12 | reverse(s.begin(), s.end()); 13 | 14 | size_t begin = 0, end = 0, len = 0; 15 | while ((begin = s.find_first_not_of(" ", end)) != string::npos) { 16 | if ((end = s.find(" ", begin)) == string::npos) { 17 | end = s.length(); 18 | } 19 | // Reverse each word in the string. 20 | reverse(s.begin() + begin, s.begin() + end); 21 | 22 | // Shift the word to avoid extra space. 23 | move(s.begin() + begin, s.begin() + end, s.begin() + len); 24 | len += end - begin; 25 | s[len++] = ' '; 26 | } 27 | s.resize(len ? len - 1 : 0); 28 | return s; 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /C++/flatten-binary-tree-to-linked-list.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(h) 3 | 4 | /** 5 | * Definition of TreeNode: 6 | * class TreeNode { 7 | * public: 8 | * int val; 9 | * TreeNode *left, *right; 10 | * TreeNode(int val) { 11 | * this->val = val; 12 | * this->left = this->right = NULL; 13 | * } 14 | * } 15 | */ 16 | class Solution { 17 | public: 18 | /** 19 | * @param root: a TreeNode, the root of the binary tree 20 | * @return: nothing 21 | */ 22 | void flatten(TreeNode *root) { 23 | TreeNode *list_head = nullptr; 24 | flattenHelper(root, &list_head); 25 | } 26 | 27 | TreeNode *flattenHelper(TreeNode *root, TreeNode **list_head) { 28 | if (root) { 29 | flattenHelper(root->right, list_head); 30 | flattenHelper(root->left, list_head); 31 | root->right = *list_head; 32 | root->left = nullptr; 33 | *list_head = root; 34 | } 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /C++/minimum-path-sum.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(m * n) 2 | // Space: O(min(m, n)) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param grid: a list of lists of integers. 8 | * @return: An integer, minimizes the sum of all numbers along its path 9 | */ 10 | int minPathSum(vector> &grid) { 11 | const int m = grid.size(); 12 | const int n = grid[0].size(); 13 | 14 | vector> sum(2, vector(n, 0)); 15 | sum[0][0] = grid[0][0]; 16 | for (int j = 1; j < n; ++j) { 17 | sum[0][j] = sum[0][j - 1] + grid[0][j]; 18 | } 19 | 20 | for (int i = 1; i < m; ++i) { 21 | sum[i % 2][0] = sum[(i - 1) % 2][0] + grid[i][0]; 22 | for (int j = 1; j < n; ++j) { 23 | sum[i % 2][j] = min(sum[(i - 1) % 2][j], sum[i % 2][j - 1]) 24 | + grid[i][j]; 25 | } 26 | } 27 | 28 | return sum[(m - 1) % 2][n - 1]; 29 | } 30 | }; 31 | 32 | -------------------------------------------------------------------------------- /C++/largest-rectangle-in-histogram.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(n) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param height: A list of integer 8 | * @return: The area of largest rectangle in the histogram 9 | */ 10 | int largestRectangleArea(vector &height) { 11 | stack increasing_height; 12 | int max_area = 0; 13 | 14 | for (int i = 0; i <= height.size();) { 15 | if (increasing_height.empty() || 16 | (i < height.size() && height[i] > height[increasing_height.top()])) { 17 | increasing_height.emplace(i); 18 | ++i; 19 | } else { 20 | auto h = height[increasing_height.top()]; 21 | increasing_height.pop(); 22 | auto left = increasing_height.empty() ? -1 : increasing_height.top(); 23 | max_area = max(max_area, h * (i - left - 1)); 24 | } 25 | } 26 | 27 | return max_area; 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /C++/valid-parentheses.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(n) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param s A string 8 | * @return whether the string is a valid parentheses 9 | */ 10 | bool isValidParentheses(string& s) { 11 | const unordered_map symbol_pair = {{')', '('}, 12 | {']', '['}, 13 | {'}', '{'}}; 14 | stack parentheses; 15 | for (const auto& c: s) { 16 | const auto& it = symbol_pair.find(c); 17 | if (it != symbol_pair.cend()) { 18 | if (parentheses.empty() || 19 | parentheses.top() != it->second) { 20 | return false; 21 | } 22 | parentheses.pop(); 23 | } else { 24 | parentheses.emplace(c); 25 | } 26 | } 27 | return parentheses.empty(); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /C++/combinations.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(k * n^k) 2 | // Space: O(k) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param n: Given the range of numbers 8 | * @param k: Given the numbers of combinations 9 | * @return: All the combinations of k numbers out of 1..n 10 | */ 11 | vector> combine(int n, int k) { 12 | vector> result; 13 | vector ans; 14 | CombinationsHelper(n, k, 1, &ans, &result); 15 | return result; 16 | } 17 | 18 | void CombinationsHelper(int n, int k, int start, vector* ans, 19 | vector>* result) { 20 | if (ans->size() == k) { 21 | result->emplace_back(*ans); 22 | return; 23 | } 24 | 25 | for (int i = start; i <= n && k - ans->size() <= n - i + 1; ++i) { 26 | ans->emplace_back(i); 27 | CombinationsHelper(n, k, i + 1, ans, result); 28 | ans->pop_back(); 29 | } 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /C++/two-lists-sum.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode(int x) : val(x), next(NULL) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | /** 15 | * @param l1: the first list 16 | * @param l2: the second list 17 | * @return: the sum list of l1 and l2 18 | */ 19 | ListNode *addLists(ListNode *l1, ListNode *l2) { 20 | ListNode dummy{0}; 21 | auto curr = &dummy; 22 | 23 | auto carry = 0; 24 | while (l1 || l2 || carry) { 25 | auto a = l1? l1->val : 0, b = l2? l2->val : 0; 26 | auto val = carry + a + b; 27 | curr->next = new ListNode(val % 10); 28 | carry = val / 10; 29 | l1 = l1 ? l1->next : nullptr; 30 | l2 = l2 ? l2->next : nullptr; 31 | curr = curr->next; 32 | } 33 | 34 | return dummy.next; 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /C++/longest-increasing-continuous-subsequence.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param A an array of Integer 8 | * @return an integer 9 | */ 10 | int longestIncreasingContinuousSubsequence(vector& A) { 11 | int max_inc_len = 0, cur_inc_len = 0; 12 | int max_dec_len = 0, cur_dec_len = 0; 13 | 14 | for (int i = 0; i < A.size(); ++i) { 15 | if (i == 0 || A[i] == A[i - 1]) { 16 | max_inc_len = max(max_inc_len, ++cur_inc_len); 17 | max_dec_len = max(max_dec_len, ++cur_dec_len); 18 | } else if (A[i] > A[i - 1]) { 19 | max_inc_len = max(max_inc_len, ++cur_inc_len); 20 | cur_dec_len = 1; 21 | } else if (A[i] < A[i - 1]) { 22 | max_dec_len = max(max_dec_len, ++cur_dec_len); 23 | cur_inc_len = 1; 24 | } 25 | } 26 | 27 | return max(max_inc_len, max_dec_len); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /C++/subsets-ii.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n * 2^n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param S: A set of numbers. 8 | * @return: A list of lists. All valid subsets. 9 | */ 10 | vector> subsetsWithDup(const vector &S) { 11 | vector sorted_S(S); 12 | sort(sorted_S.begin(), sorted_S.end()); 13 | vector> result(1); 14 | size_t previous_size = 0; 15 | for (size_t i = 0; i < sorted_S.size(); ++i) { 16 | const size_t size = result.size(); 17 | for (size_t j = 0; j < size; ++j) { 18 | // only union non-duplicate element or new union set 19 | if (i == 0 || sorted_S[i] != sorted_S[i - 1] || j >= previous_size) { 20 | result.emplace_back(result[j]); 21 | result.back().emplace_back(sorted_S[i]); 22 | } 23 | } 24 | previous_size = size; 25 | } 26 | return result; 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /C++/house-robber-iii.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(h) 3 | 4 | /** 5 | * Definition of TreeNode: 6 | * class TreeNode { 7 | * public: 8 | * int val; 9 | * TreeNode *left, *right; 10 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 11 | * } 12 | */ 13 | class Solution { 14 | public: 15 | /** 16 | * @param root: The root of binary tree. 17 | * @return: The maximum amount of money you can rob tonight 18 | */ 19 | int houseRobber3(TreeNode* root) { 20 | const auto& res = houseRobber3Helper(root); 21 | return max(res.first, res.second); 22 | } 23 | 24 | private: 25 | pair houseRobber3Helper(TreeNode* root) { 26 | if (!root) { 27 | return {0, 0}; 28 | } 29 | const auto& left = houseRobber3Helper(root->left); 30 | const auto& right = houseRobber3Helper(root->right); 31 | return {root->val + left.second + right.second, 32 | max(left.first, left.second) + max(right.first, right.second)}; 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /C++/rotate-list.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode(int x) : val(x), next(NULL) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | /** 15 | * @param head: the list 16 | * @param k: rotate to the right k places 17 | * @return: the list after rotation 18 | */ 19 | ListNode *rotateRight(ListNode *head, int k) { 20 | if (head == nullptr || head->next == nullptr) { 21 | return head; 22 | } 23 | 24 | int n = 1; 25 | ListNode *cur = head; 26 | for (; cur->next; cur = cur->next) { 27 | ++n; 28 | } 29 | cur->next = head; 30 | 31 | ListNode *tail = cur; 32 | k = n - k % n; 33 | cur = head; 34 | for (int i = 0; i < k; cur = cur->next, ++i) { 35 | tail = cur; 36 | } 37 | 38 | tail->next = nullptr; 39 | return cur; 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /C++/house-robber-ii.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param nums: An array of non-negative integers. 8 | * return: The maximum amount of money you can rob tonight 9 | */ 10 | int houseRobber2(vector& nums) { 11 | if (nums.size() == 0) { 12 | return 0; 13 | } 14 | if (nums.size() == 1) { 15 | return nums[0]; 16 | } 17 | 18 | return max(robRange(nums, 0, nums.size() - 1), // Include the first one of nums without the last one. 19 | robRange(nums, 1, nums.size())); // Include the last one of nums without the first one. 20 | } 21 | 22 | int robRange(vector& nums, int start, int end) { 23 | int num_i = nums[start], num_i_1 = 0, num_i_2 = 0; 24 | for (int i = start + 1; i < end; ++i) { 25 | num_i_2 = num_i_1; 26 | num_i_1 = num_i; 27 | num_i = max(nums[i] + num_i_2, num_i_1); 28 | } 29 | return num_i; 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /C++/nth-to-last-node-in-list.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n), n is the lengh of the linked list. 2 | // Space: O(1) 3 | 4 | /** 5 | * Definition of ListNode 6 | * class ListNode { 7 | * public: 8 | * int val; 9 | * ListNode *next; 10 | * ListNode(int val) { 11 | * this->val = val; 12 | * this->next = NULL; 13 | * } 14 | * } 15 | */ 16 | class Solution { 17 | public: 18 | /** 19 | * @param head: The first node of linked list. 20 | * @param n: An integer. 21 | * @return: Nth to last node of a singly linked list. 22 | */ 23 | ListNode *nthToLast(ListNode *head, int n) { 24 | auto slow = head, fast = head; 25 | 26 | // fast is n-step ahead. 27 | while (n > 0) { 28 | fast = fast->next; 29 | --n; 30 | } 31 | 32 | // When fast reaches the end, slow must be nth to last node. 33 | while (fast != nullptr) { 34 | slow = slow->next; 35 | fast = fast->next; 36 | } 37 | 38 | return slow; 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /C++/unique-paths-ii.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(m * n) 2 | // Space: O(min(m, n)) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param obstacleGrid: A list of lists of integers 8 | * @return: An integer 9 | */ 10 | int uniquePathsWithObstacles(vector> &obstacleGrid) { 11 | const int m = obstacleGrid.size(); 12 | const int n = obstacleGrid[0].size(); 13 | 14 | vector> path(2, vector(n, 0)); 15 | 16 | path[0][0] = obstacleGrid[0][0] == 0? 1 : 0; 17 | for (int j = 1; j < n; ++j) { 18 | path[0][j] = obstacleGrid[0][j] == 0? path[0][j - 1] : 0; 19 | } 20 | 21 | for (int i = 1; i < m; ++i) { 22 | path[i % 2][0] = obstacleGrid[i][0] == 0? path[(i - 1) % 2][0] : 0; 23 | for (int j = 1; j < n; ++j) { 24 | path[i % 2][j] = obstacleGrid[i][j] == 0? 25 | path[(i - 1) % 2][j] + path[i % 2][j - 1] : 0; 26 | } 27 | } 28 | 29 | return path[(m - 1) % 2][n - 1]; 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /C++/dices-sum.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n^2) 2 | // Space: O(n) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param n an integer 8 | * @return a list of pair 9 | */ 10 | vector> dicesSum(int n) { 11 | vector> result; 12 | vector> dp(2, vector(6 * n + 1)); 13 | 14 | for (int i = 1; i <= 6; ++i) { 15 | dp[1][i] = 1.0 / 6; 16 | } 17 | 18 | for (int i = 2; i <= n; ++i) { 19 | for (int j = 1; j <= 6 * i; ++j) { 20 | dp[i % 2][j] = 0.0; 21 | for (int k = 1; k <= 6; ++k) { 22 | if (j > k) { 23 | dp[i % 2][j] += dp[(i - 1) % 2][j - k]; 24 | } 25 | } 26 | dp[i % 2][j] /= 6.0; 27 | } 28 | } 29 | 30 | for (int i = n; i <= 6 * n; ++i) { 31 | result.emplace_back(i, dp[n % 2][i]); 32 | } 33 | 34 | return result; 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /C++/longest-substring-without-repeating-characters.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param s: a string 8 | * @return: an integer 9 | */ 10 | int lengthOfLongestSubstring(string s) { 11 | // Record the last occurrence of each char. 12 | unordered_map last_occurrence; 13 | size_t starting_idx = 0, ans = 0; 14 | for (size_t i = 0; i < s.size(); ++i) { 15 | auto it(last_occurrence.find(s[i])); 16 | if (it == last_occurrence.cend()) { 17 | last_occurrence.emplace_hint(it, s[i], i); 18 | } else { // s[i] appeared before. Check its validity. 19 | if (it->second >= starting_idx) { 20 | ans = max(ans, i - starting_idx); 21 | starting_idx = it->second + 1; 22 | } 23 | it->second = i; 24 | } 25 | } 26 | ans = max(ans, s.size() - starting_idx); 27 | return ans; 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /C++/gray-code.cpp: -------------------------------------------------------------------------------- 1 | // Time: (2^n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param n a number 8 | * @return Gray code 9 | */ 10 | vector grayCode(int n) { 11 | vector result = {0}; 12 | for (int i = 0; i < n; ++i) { 13 | for (int j = result.size() - 1; j >= 0; --j) { 14 | result.emplace_back(1 << i | result[j]); 15 | } 16 | } 17 | return result; 18 | } 19 | }; 20 | 21 | // Time: (2^n) 22 | // Space: O(1) 23 | // Proof of closed form formula could be found here: 24 | // http://math.stackexchange.com/questions/425894/proof-of-closed-form-formula-to-convert-a-binary-number-to-its-gray-code 25 | class Solution2 { 26 | public: 27 | /** 28 | * @param n a number 29 | * @return Gray code 30 | */ 31 | vector grayCode(int n) { 32 | vector result; 33 | for (int i = 0; i < 1 << n; ++i) { 34 | result.emplace_back(i >> 1 ^ i); 35 | } 36 | return result; 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /C++/search-a-2d-matrix-ii.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(m + n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param matrix: A list of lists of integers 8 | * @param target: An integer you want to search in matrix 9 | * @return: An integer indicate the total occurrence of target in the given matrix 10 | */ 11 | int searchMatrix(vector> &matrix, int target) { 12 | const int m = matrix.size(); 13 | if (m == 0) { 14 | return 0; 15 | } 16 | const int n = matrix[0].size(); 17 | if (n == 0) { 18 | return 0; 19 | } 20 | int count = 0; 21 | 22 | int i = 0, j = n - 1; 23 | while (i < m && j >= 0) { 24 | if (matrix[i][j] == target) { 25 | ++count; 26 | ++i; 27 | --j; 28 | } else if (matrix[i][j] > target) { 29 | --j; 30 | } else { 31 | ++i; 32 | } 33 | } 34 | 35 | return count; 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /C++/validate-binary-search-tree.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(h) 3 | 4 | /** 5 | * Definition of TreeNode: 6 | * class TreeNode { 7 | * public: 8 | * int val; 9 | * TreeNode *left, *right; 10 | * TreeNode(int val) { 11 | * this->val = val; 12 | * this->left = this->right = NULL; 13 | * } 14 | * } 15 | */ 16 | class Solution { 17 | public: 18 | /** 19 | * @param root: The root of binary tree. 20 | * @return: True if the binary tree is BST, or false 21 | */ 22 | bool isValidBST(TreeNode *root) { 23 | if (!root) { 24 | return true; 25 | } 26 | 27 | if (!isValidBST(root->left)) { 28 | return false; 29 | } 30 | 31 | if (last && last != root && last->val >= root->val) { 32 | return false; 33 | } 34 | 35 | last = root; 36 | 37 | if (!isValidBST(root->right)) { 38 | return false; 39 | } 40 | 41 | return true; 42 | } 43 | 44 | private: 45 | TreeNode *last = nullptr; 46 | }; 47 | -------------------------------------------------------------------------------- /C++/space-replacement.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param string: An array of Char 8 | * @param length: The true length of the string 9 | * @return: The true length of new string 10 | */ 11 | int replaceBlank(char string[], int length) { 12 | const array to{'%', '2', '0'}; 13 | 14 | int space_count = 0; 15 | for (int i = 0; i < length; ++i) { 16 | if (string[i] == ' ') { 17 | ++space_count; 18 | } 19 | } 20 | 21 | const int new_length = length + 22 | (static_cast(to.size()) - 1) * space_count; 23 | for (int i = length - 1, j = new_length - 1; i >= 0; --i) { 24 | if (string[i] == ' ') { 25 | j -= to.size(); 26 | copy(to.cbegin(), to.cend(), string + j + 1); 27 | } else { 28 | string[j--] = string[i]; 29 | } 30 | } 31 | 32 | return new_length; 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /C++/k-sum-ii.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(k * C(n, k)) 2 | // Space: O(k) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param A: an integer array. 8 | * @param k: a positive integer (k <= length(A)) 9 | * @param target: a integer 10 | * @return a list of lists of integer 11 | */ 12 | vector> kSumII(vector A, int k, int target) { 13 | vector> ans; 14 | vector curr; 15 | helper(A, k, 0, target, curr, ans); 16 | return ans; 17 | } 18 | 19 | void helper(vector A, int k, int start, int target, vector& curr, vector> & ans) { 20 | if (k < 0 || target < 0) { 21 | return; 22 | } 23 | 24 | if (k == 0 && target == 0) { 25 | ans.emplace_back(curr); 26 | return; 27 | } 28 | 29 | for (int i = start; i <= A.size() - k; i++) { 30 | curr.emplace_back(A[i]); 31 | helper(A, k - 1, i + 1, target - A[i], curr, ans); 32 | curr.pop_back(); 33 | } 34 | } 35 | }; 36 | 37 | -------------------------------------------------------------------------------- /C++/assignment-operator-overloading-c-only.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | char *m_pData; 7 | Solution() { 8 | this->m_pData = NULL; 9 | } 10 | Solution(char *pData) { 11 | this->m_pData = pData; 12 | } 13 | 14 | // Implement an assignment operator 15 | Solution operator=(const Solution &object) { 16 | if (this != &object) { 17 | // 1: Allocate new memory and copy the elements. 18 | char *new_pData = nullptr; 19 | if (object.m_pData != nullptr) { 20 | size_t count = strlen(object.m_pData); 21 | new_pData = new char[count]; 22 | copy(object.m_pData, object.m_pData + count, new_pData); 23 | } 24 | 25 | // 2: Deallocate old memory. 26 | if (m_pData != nullptr) { 27 | delete[] m_pData; 28 | } 29 | 30 | // 3: Assign the new memory to the object. 31 | m_pData = new_pData;; 32 | } 33 | return *this; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /C++/generate-parentheses.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n * (C(2n, n) - C(2n, n - 1))) = Catalan numbers 2 | // Space: O(n) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param n n pairs 8 | * @return All combinations of well-formed parentheses 9 | */ 10 | vector generateParenthesis(int n) { 11 | vector result; 12 | string cur; 13 | generateParenthesisHelper(n, n, &cur, &result); 14 | return result; 15 | } 16 | 17 | void generateParenthesisHelper( 18 | int left, int right, 19 | string *cur, vector *result) { 20 | 21 | if (!left && !right) { 22 | result->emplace_back(*cur); 23 | } 24 | if (left > 0) { 25 | cur->push_back('('); 26 | generateParenthesisHelper(left - 1, right, cur, result); 27 | cur->pop_back(); 28 | } 29 | if (left < right) { 30 | cur->push_back(')'); 31 | generateParenthesisHelper(left, right - 1, cur, result); 32 | cur->pop_back(); 33 | } 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /C++/merge-two-sorted-lists.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | /** 5 | * Definition of ListNode 6 | * class ListNode { 7 | * public: 8 | * int val; 9 | * ListNode *next; 10 | * ListNode(int val) { 11 | * this->val = val; 12 | * this->next = NULL; 13 | * } 14 | * } 15 | */ 16 | class Solution { 17 | public: 18 | /** 19 | * @param ListNode l1 is the head of the linked list 20 | * @param ListNode l2 is the head of the linked list 21 | * @return: ListNode head of linked list 22 | */ 23 | ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) { 24 | ListNode dummy{0}; 25 | auto curr = &dummy; 26 | 27 | while (l1 && l2) { 28 | if (l1->val <= l2->val) { 29 | curr->next = l1; 30 | l1 = l1->next; 31 | } else { 32 | curr->next = l2; 33 | l2 = l2->next; 34 | } 35 | curr = curr->next; 36 | } 37 | curr->next = l1 ? l1 : l2; 38 | 39 | return dummy.next; 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /C++/wiggle-sort-ii.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) ~ O(n^2), O(n) on average 2 | // Space: O(1) 3 | 4 | // Tri Partition (aka Dutch National Flag Problem) with virtual index solution. 5 | class Solution { 6 | public: 7 | /** 8 | * @param nums a list of integer 9 | * @return void 10 | */ 11 | void wiggleSort(vector& nums) { 12 | int mid = (nums.size() - 1) / 2; 13 | nth_element(nums.begin(), nums.begin() + mid, nums.end()); // O(n) ~ O(n^2) time 14 | reversedTriPartitionWithVI(nums, nums[mid]); // O(n) time, O(1) space 15 | } 16 | 17 | void reversedTriPartitionWithVI(vector& nums, int val) { 18 | const int N = nums.size() / 2 * 2 + 1; 19 | #define Nums(i) nums[(1 + 2 * (i)) % N] 20 | for (int i = 0, j = 0, n = nums.size() - 1; j <= n;) { 21 | if (Nums(j) > val) { 22 | swap(Nums(i++), Nums(j++)); 23 | } else if (Nums(j) < val) { 24 | swap(Nums(j), Nums(n--)); 25 | } else { 26 | ++j; 27 | } 28 | } 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /C++/max-tree.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(n) 3 | 4 | /** 5 | * Definition of TreeNode: 6 | * class TreeNode { 7 | * public: 8 | * int val; 9 | * TreeNode *left, *right; 10 | * TreeNode(int val) { 11 | * this->val = val; 12 | * this->left = this->right = NULL; 13 | * } 14 | * } 15 | */ 16 | class Solution { 17 | public: 18 | /** 19 | * @param A: Given an integer array with no duplicates. 20 | * @return: The root of max tree. 21 | */ 22 | TreeNode* maxTree(vector A) { 23 | vector nodeStack; 24 | for (int i = 0; i < A.size(); ++i) { 25 | auto node = new TreeNode(A[i]); 26 | while (!nodeStack.empty() && A[i] > nodeStack.back()->val) { 27 | node->left = nodeStack.back(); 28 | nodeStack.pop_back(); 29 | } 30 | if (!nodeStack.empty()) { 31 | nodeStack.back()->right = node; 32 | } 33 | nodeStack.emplace_back(node); 34 | } 35 | return nodeStack.front(); 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /C++/find-the-missing-number.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param nums: a vector of integers 8 | * @return: an integer 9 | */ 10 | int findMissing(vector &nums) { 11 | int missing_num = 0; 12 | // xor all nums <= N. 13 | for (int num = 0; num <= nums.size(); ++num) { 14 | missing_num ^= num; 15 | } 16 | // Delete num in nums. 17 | for (const auto& num : nums) { 18 | missing_num ^= num; 19 | } 20 | // The remaining num would be missing num. 21 | return missing_num; 22 | } 23 | }; 24 | 25 | // Time: O(n) 26 | // Space: O(n) 27 | class Solution2 { 28 | public: 29 | int findMissing(vector &nums) { 30 | vector expected(nums.size()); 31 | iota(expected.begin(), expected.end(), 1); // Costs extra space O(n) 32 | return accumulate(nums.cbegin(), nums.cend(), 0, bit_xor()) ^ 33 | accumulate(expected.cbegin(), expected.cend(), 0, bit_xor()); 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /C++/combination-sum.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(k * n^k), k is max length of combination 2 | // Space: O(k) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param num: Given the candidate numbers 8 | * @param target: Given the target number 9 | * @return: All the combinations that sum to target 10 | */ 11 | vector> combinationSum(vector &num, int target) { 12 | sort(num.begin(), num.end()); 13 | vector> ans; 14 | vector v; 15 | combinationSumHelper(num, target, 0, v, ans); 16 | return ans; 17 | } 18 | 19 | private: 20 | void combinationSumHelper(vector& num, int gap, int begin, 21 | vector& v,vector> &ans) { 22 | if (gap == 0) { 23 | ans.emplace_back(v); 24 | return; 25 | } 26 | 27 | for (size_t i = begin; i < num.size() && num[i] <= gap; ++i) { 28 | v.emplace_back(num[i]); 29 | combinationSumHelper(num, gap - num[i], i, v, ans); 30 | v.pop_back(); 31 | } 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /C++/remove-duplicates-from-sorted-list-ii.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | /** 5 | * Definition of ListNode 6 | * class ListNode { 7 | * public: 8 | * int val; 9 | * ListNode *next; 10 | * ListNode(int val) { 11 | * this->val = val; 12 | * this->next = NULL; 13 | * } 14 | * } 15 | */ 16 | class Solution{ 17 | public: 18 | /** 19 | * @param head: The first node of linked list. 20 | * @return: head node 21 | */ 22 | ListNode * deleteDuplicates(ListNode *head) { 23 | ListNode dummy{0}; 24 | auto prev = &dummy; 25 | while (head) { 26 | if (head->next && head->next->val == head->val) { 27 | auto val = head->val; 28 | while (head && head->val == val) { 29 | head = head->next; 30 | } 31 | prev->next = head; 32 | } else { 33 | prev->next = head; 34 | prev = head; 35 | head = head->next; 36 | } 37 | } 38 | return dummy.next; 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /C++/string-to-integeratoi.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param str: A string 8 | * @return An integer 9 | */ 10 | int atoi(string str) { 11 | if (str.empty()) { 12 | return 0; 13 | } 14 | 15 | int ans = 0; 16 | int sign = 1; 17 | int i = 0; 18 | 19 | // Skip ' '. 20 | while (str[i] == ' ') { 21 | ++i; 22 | } 23 | 24 | // Parse sign. 25 | if (str[i] == '+') { 26 | ++i; 27 | } else if (str[i] == '-') { 28 | sign = -1; 29 | ++i; 30 | } 31 | 32 | // Compute integer. 33 | for (; i < str.length() && isdigit(str[i]); ++i) { 34 | if (ans > (numeric_limits::max() - (str[i] - '0')) / 10) { 35 | return sign > 0 ? numeric_limits::max() : numeric_limits::min(); 36 | } 37 | ans *= 10; 38 | ans += str[i] - '0'; 39 | } 40 | 41 | ans *= sign; 42 | return ans; 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /C++/sort-colors-ii.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | // Inplace counting sort. 5 | class Solution{ 6 | public: 7 | /** 8 | * @param colors: A list of integer 9 | * @param k: An integer 10 | * @return: nothing 11 | */ 12 | void sortColors2(vector &colors, int k) { 13 | for (int i = 0; i < colors.size(); ++i) { 14 | if (colors[i] > 0) { 15 | int pos = colors[i] - 1; 16 | if (colors[pos] <= 0) { // Bucket exists. 17 | --colors[pos]; 18 | colors[i] = 0; 19 | } 20 | else { // Init a new bucket. 21 | colors[i] = colors[pos]; 22 | colors[pos] = -1; 23 | --i; 24 | } 25 | } 26 | } 27 | 28 | for (int i = colors.size() - 1, pos = k - 1; pos >= 0; --pos) { 29 | while (colors[pos] < 0) { // Reorder the color by count of each bucket. 30 | ++colors[pos]; 31 | colors[i--] = pos + 1; 32 | } 33 | } 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /C++/super-ugly-number.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n * logk) ~ O(n * k) 2 | // Space: O(n + k) 3 | 4 | // Heap solution. (308ms) 5 | class Solution { 6 | public: 7 | /** 8 | * @param n a positive integer 9 | * @param primes the given prime list 10 | * @return the nth super ugly number 11 | */ 12 | int nthSuperUglyNumber(int n, vector& primes) { 13 | priority_queue, 14 | vector>, 15 | greater>> heap; 16 | vector uglies(n), idx(primes.size()), ugly_by_last_prime(n); 17 | uglies[0] = 1; 18 | 19 | for (int i = 0; i < primes.size(); ++i) { 20 | heap.emplace(primes[i], i); 21 | } 22 | for (int i = 1; i < n; ++i) { 23 | int k; 24 | tie(uglies[i], k) = heap.top(); 25 | heap.pop(); 26 | ugly_by_last_prime[i] = k; 27 | while (ugly_by_last_prime[++idx[k]] > k); // worst time: O(k) 28 | heap.emplace(uglies[idx[k]] * primes[k], k); 29 | } 30 | return uglies[n - 1]; 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /C++/burst-balloons.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n^3) 2 | // Space: O(n^2) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param nums a list of integer 8 | * @return an integer, maximum coins 9 | */ 10 | int maxCoins(vector& nums) { 11 | vector coins; 12 | coins.emplace_back(1); 13 | for (const auto& n : nums) { 14 | if (n > 0) { 15 | coins.emplace_back(n); 16 | } 17 | } 18 | coins.emplace_back(1); 19 | 20 | vector> max_coins(coins.size(), vector(coins.size())); 21 | for (int k = 2; k < coins.size(); ++k) { 22 | for (int left = 0; left < coins.size() - k; ++left) { 23 | for (int i = left + 1, right = left + k; i < right; ++i) { 24 | max_coins[left][right] = max(max_coins[left][right], 25 | coins[left] * coins[i] * coins[right] + 26 | max_coins[left][i] + max_coins[i][right]); 27 | } 28 | } 29 | } 30 | 31 | return max_coins[0][coins.size() - 1]; 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /C++/balanced-binary-tree.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(h) 3 | 4 | /** 5 | * Definition of TreeNode: 6 | * class TreeNode { 7 | * public: 8 | * int val; 9 | * TreeNode *left, *right; 10 | * TreeNode(int val) { 11 | * this->val = val; 12 | * this->left = this->right = NULL; 13 | * } 14 | * } 15 | */ 16 | class Solution { 17 | public: 18 | /** 19 | * @param root: The root of binary tree. 20 | * @return: True if this Binary tree is Balanced, or false. 21 | */ 22 | bool isBalanced(TreeNode *root) { 23 | return isBalancedRecu(root).first; 24 | } 25 | 26 | pair isBalancedRecu(TreeNode *root) { 27 | if (root == nullptr) { 28 | return {true, 0}; 29 | } 30 | 31 | pair left = isBalancedRecu(root->left); 32 | pair right = isBalancedRecu(root->right); 33 | 34 | if (left.first && right.first && abs(left.second - right.second) <= 1) { 35 | return {true, max(left.second, right.second) + 1}; 36 | } 37 | else { 38 | return {false, 0}; 39 | } 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /C++/wood-cut.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(nlogL) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | *@param L: Given n pieces of wood with length L[i] 8 | *@param k: An integer 9 | *return: The maximum length of the small pieces. 10 | */ 11 | int woodCut(vector L, int k) { 12 | const int n = L.size(); 13 | if (n == 0) { 14 | return 0; 15 | } 16 | 17 | int left = 1, right = *max_element(L.cbegin(), L.cend()); 18 | while (left <= right) { 19 | const auto mid = left + (right - left) / 2; 20 | 21 | // Find the smallest x, s.t. pieceCount(x) < k <= pieceCound(x - 1) 22 | if (pieceCount(L, mid) < k) { 23 | right = mid - 1; 24 | } else { 25 | left = mid + 1; 26 | } 27 | } 28 | 29 | // The max length is x - 1 30 | return left - 1; 31 | } 32 | 33 | private: 34 | int pieceCount(vector& L, int x) { 35 | int cnt = 0; 36 | for (const auto& len : L) { 37 | cnt += len / x; 38 | } 39 | return cnt; 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /C++/next-permutation-ii.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param nums: a vector of integers 8 | * @return: return nothing (void), do not return anything, modify nums in-place instead 9 | */ 10 | void nextPermutation(vector &nums) { 11 | int k = -1, l = 0; 12 | for (int i = 0; i < nums.size() - 1; ++i) { 13 | if (nums[i] < nums[i + 1]) { 14 | k = i; 15 | } 16 | } 17 | 18 | if (k >= 0) { 19 | for (int i = 0; i < nums.size(); ++i) { 20 | if (nums[i] > nums[k]) { 21 | l = i; 22 | } 23 | } 24 | swap(nums[k], nums[l]); 25 | } 26 | reverse(nums.begin() + k + 1, nums.end()); 27 | } 28 | }; 29 | 30 | class Solution2 { 31 | public: 32 | /** 33 | * @param nums: a vector of integers 34 | * @return: return nothing (void), do not return anything, modify nums in-place instead 35 | */ 36 | void nextPermutation(vector &nums) { 37 | next_permutation(nums.begin(), nums.end()); 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /C++/perfect-squares.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n * sqrt(n)) 2 | // Space: O(n) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param n a positive integer 8 | * @return an integer 9 | */ 10 | int numSquares(int n) { 11 | static vector num{0}; 12 | while (num.size() <= n) { 13 | int squares = numeric_limits::max(); 14 | for (int i = 1; i * i <= num.size(); ++i) { 15 | squares = min(squares, num[num.size() - i * i] + 1); 16 | } 17 | num.emplace_back(squares); 18 | } 19 | return num[n]; 20 | } 21 | }; 22 | 23 | 24 | // Time: O(n * sqrt(n)) 25 | // Space: O(n) 26 | class Solution2 { 27 | public: 28 | /** 29 | * @param n a positive integer 30 | * @return an integer 31 | */ 32 | int numSquares(int n) { 33 | vector num(n + 1, numeric_limits::max()); 34 | num[0] = 0; 35 | for (int i = 0; i <= n; ++i) { 36 | for (int j = i - 1, k = 1; j >= 0; ++k, j = i - k * k) { 37 | num[i] = min(num[i], num[j] + 1); 38 | } 39 | } 40 | return num[n]; 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 https://github.com/kamyu104/LintCode 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /C++/partition-list.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | /** 5 | * Definition of ListNode 6 | * class ListNode { 7 | * public: 8 | * int val; 9 | * ListNode *next; 10 | * ListNode(int val) { 11 | * this->val = val; 12 | * this->next = NULL; 13 | * } 14 | * } 15 | */ 16 | class Solution { 17 | public: 18 | /** 19 | * @param head: The first node of linked list. 20 | * @param x: an integer 21 | * @return: a ListNode 22 | */ 23 | ListNode *partition(ListNode *head, int x) { 24 | ListNode dummy_smaller{0}; 25 | ListNode dummy_larger{0}; 26 | auto smaller = &dummy_smaller; 27 | auto larger = &dummy_larger; 28 | 29 | while (head) { 30 | if (head->val < x) { 31 | smaller->next = head; 32 | smaller = smaller->next; 33 | } else { 34 | larger->next = head; 35 | larger = larger->next; 36 | } 37 | head = head->next; 38 | } 39 | smaller->next = dummy_larger.next; 40 | larger->next = nullptr; 41 | 42 | return dummy_smaller.next; 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /C++/fast-power.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(logn) 2 | // Space: O(1) 3 | 4 | // Iterative solution. 5 | class Solution { 6 | public: 7 | /* 8 | * @param a, b, n: 32bit integers 9 | * @return: An integer 10 | */ 11 | int fastPower(int a, int b, int n) { 12 | long long result = 1; 13 | long long x = a % b; 14 | while (n > 0) { 15 | if (n & 1) { 16 | result = result * x % b; 17 | } 18 | n >>= 1; 19 | x = x * x % b; 20 | } 21 | return result % b; 22 | } 23 | }; 24 | 25 | // Time: O(logn) 26 | // Space: O(logn) 27 | // Recursive solution. 28 | class Solution2 { 29 | public: 30 | /* 31 | * @param a, b, n: 32bit integers 32 | * @return: An integer 33 | */ 34 | int fastPower(int a, int b, int n) { 35 | if (n == 0) { 36 | return 1 % b; 37 | } 38 | if (n == 1) { 39 | return a % b; 40 | } 41 | long long tmp = fastPower(a, b, n / 2); 42 | if (n % 2 == 0) { 43 | return (tmp * tmp) % b; 44 | } else { 45 | return ((tmp * tmp) % b * a) % b; 46 | } 47 | } 48 | }; 49 | -------------------------------------------------------------------------------- /C++/merge-intervals.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(nlogn) 2 | // Space: O(1) 3 | 4 | /** 5 | * Definition of Interval: 6 | * classs Interval { 7 | * int start, end; 8 | * Interval(int start, int end) { 9 | * this->start = start; 10 | * this->end = end; 11 | * } 12 | */ 13 | class Solution { 14 | public: 15 | /** 16 | * @param intervals: interval list. 17 | * @return: A new interval list. 18 | */ 19 | vector merge(vector &intervals) { 20 | if (intervals.empty()) { 21 | return intervals; 22 | } 23 | 24 | sort(intervals.begin(), intervals.end(), 25 | [](const Interval& a, const Interval& b) { 26 | return a.start < b.start; 27 | }); 28 | 29 | vector result = {intervals[0]}; 30 | for (int i = 1; i < intervals.size(); ++i) { 31 | Interval& prev = result.back(); 32 | if (intervals[i].start <= prev.end) { 33 | prev.end = max(prev.end, intervals[i].end); 34 | } else { 35 | result.emplace_back(intervals[i]); 36 | } 37 | } 38 | 39 | return result; 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /C++/paint-house.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param costs n x 3 cost matrix 8 | * @return an integer, the minimum cost to paint all houses 9 | */ 10 | int minCost(vector>& costs) { 11 | if (costs.empty()) { 12 | return 0; 13 | } 14 | 15 | vector> min_cost(2, costs[0]); 16 | 17 | const int n = costs.size(); 18 | for (int i = 1; i < n; ++i) { 19 | min_cost[i % 2][0] = costs[i][0] + 20 | min(min_cost[(i - 1) % 2][1], 21 | min_cost[(i - 1) % 2][2]); 22 | min_cost[i % 2][1] = costs[i][1] + 23 | min(min_cost[(i - 1) % 2][0], 24 | min_cost[(i - 1) % 2][2]); 25 | min_cost[i % 2][2] = costs[i][2] + 26 | min(min_cost[(i - 1) % 2][0], 27 | min_cost[(i - 1) % 2][1]); 28 | } 29 | 30 | return min(min_cost[(n - 1) % 2][0], 31 | min(min_cost[(n - 1) % 2][1], min_cost[(n - 1) % 2][2])); 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /C++/unique-binary-search-trees.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | // Catalan Number: C(2n, n) - C(2n, n - 1) 5 | class Solution { 6 | public: 7 | /** 8 | * @paramn n: An integer 9 | * @return: An integer 10 | */ 11 | int numTrees(int n) { 12 | if (n == 0) { 13 | return 1; 14 | } 15 | return combination(2 * n, n) - combination(2 * n, n - 1); 16 | } 17 | 18 | int combination(const int n, const int k) { 19 | long long count = 1; 20 | // C(n, k) = (n) / 1 * (n - 1) / 2 ... * (n - k + 1) / k 21 | for (int i = 1; i <= k; ++i) { 22 | count = count * (n - i + 1) / i; 23 | } 24 | 25 | return count; 26 | } 27 | }; 28 | 29 | // Time: O(n^2) 30 | // Space: O(n) 31 | class Solution2 { 32 | public: 33 | /** 34 | * @paramn n: An integer 35 | * @return: An integer 36 | */ 37 | int numTrees(int n) { 38 | vector num(n + 1, 0); 39 | num[0] = 1; 40 | for (int i = 1; i <= n; ++i) { 41 | for (int j = 0; j < i; ++j) { 42 | num[i] += num[j] * num[i - 1 - j]; 43 | } 44 | } 45 | return num[n]; 46 | } 47 | }; 48 | -------------------------------------------------------------------------------- /C++/insertion-sort-list.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n^2) 2 | // Space: O(1) 3 | 4 | /** 5 | * Definition of ListNode 6 | * class ListNode { 7 | * public: 8 | * int val; 9 | * ListNode *next; 10 | * ListNode(int val) { 11 | * this->val = val; 12 | * this->next = NULL; 13 | * } 14 | * } 15 | */ 16 | class Solution { 17 | public: 18 | /** 19 | * @param head: The first node of linked list. 20 | * @return: The head of linked list. 21 | */ 22 | ListNode *insertionSortList(ListNode *head) { 23 | ListNode dummy{numeric_limits::min()}; 24 | 25 | auto curr = head; 26 | ListNode *position = nullptr; 27 | 28 | while (curr) { 29 | position = findInsertPosition(&dummy, curr->val); 30 | ListNode *tmp = curr->next; 31 | curr->next = position->next; 32 | position->next = curr; 33 | curr = tmp; 34 | } 35 | 36 | return dummy.next; 37 | } 38 | 39 | ListNode* findInsertPosition(ListNode *head, int x) { 40 | ListNode *prev = nullptr; 41 | for (auto curr = head; curr && curr->val <= x; 42 | prev = curr, curr = curr->next); 43 | return prev; 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /C++/evaluate-reverse-polish-notation.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(n) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param tokens The Reverse Polish Notation 8 | * @return the value 9 | */ 10 | int evalRPN(vector& tokens) { 11 | if (tokens.empty()) { 12 | return 0; 13 | } 14 | stack s; 15 | for (const auto& tok : tokens) { 16 | if (!is_operator(tok)) { 17 | s.emplace(tok); 18 | } else { 19 | int y = stoi(s.top()); 20 | s.pop(); 21 | int x = stoi(s.top()); 22 | s.pop(); 23 | if (tok[0] == '+') { 24 | x += y; 25 | } else if (tok[0] == '-') { 26 | x -= y; 27 | } else if (tok[0] == '*') { 28 | x *= y; 29 | } else { 30 | x /= y; 31 | } 32 | s.emplace(to_string(x)); 33 | } 34 | } 35 | return stoi(s.top()); 36 | } 37 | 38 | bool is_operator(const string &op) { 39 | return op.length() == 1 && string("+-*/").find(op) != string::npos; 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /C++/remove-nth-node-from-end-of-list.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | /** 5 | * Definition of ListNode 6 | * class ListNode { 7 | * public: 8 | * int val; 9 | * ListNode *next; 10 | * ListNode(int val) { 11 | * this->val = val; 12 | * this->next = NULL; 13 | * } 14 | * } 15 | */ 16 | class Solution { 17 | public: 18 | /** 19 | * @param head: The first node of linked list. 20 | * @param n: An integer. 21 | * @return: The head of linked list. 22 | */ 23 | ListNode *removeNthFromEnd(ListNode *head, int n) { 24 | ListNode dummy{0}; 25 | dummy.next = head; 26 | auto slow = &dummy; 27 | auto fast = &dummy; 28 | 29 | // fast is n-step ahead. 30 | while (n > 0) { 31 | fast = fast->next; 32 | --n; 33 | } 34 | 35 | // When fast reaches the end, slow must be nth to last node. 36 | while (fast->next != nullptr) { 37 | slow = slow->next; 38 | fast = fast->next; 39 | } 40 | 41 | auto node_to_delete = slow->next; 42 | slow->next = slow->next->next; 43 | delete node_to_delete; 44 | 45 | return dummy.next; 46 | } 47 | }; 48 | -------------------------------------------------------------------------------- /C++/gas-station.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | // Greedy solution. 5 | class Solution { 6 | public: 7 | /** 8 | * @param gas: a vector of integers 9 | * @param cost: a vector of integers 10 | * @return: an integer 11 | */ 12 | int canCompleteCircuit(vector &gas, vector &cost) { 13 | int current_sum = 0; 14 | int total_sum = 0; 15 | int start = 0; 16 | for (int i = 0; i < gas.size(); ++i) { 17 | current_sum += gas[i] - cost[i]; 18 | total_sum += gas[i] - cost[i]; 19 | if (current_sum < 0) { 20 | // It means any gas station in range [start, i] cannot be start. 21 | current_sum = 0; 22 | start = i + 1; 23 | } 24 | } 25 | 26 | // Check if solution exists, i.e. sum(gas) >= sum(cost). 27 | if (total_sum >= 0) { 28 | // 1. route of [start, len(gas) - 1] must be positive 29 | // 2. route of [0, start - 1] must be negative 30 | // 3. sum(gas) >= sum(cost), so 1 + 2 >= 0 31 | // According to the above, start is the gas station we want. 32 | return start; 33 | } 34 | 35 | return -1; 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /C++/permutations-ii.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n * n!) 2 | // Space: O(n) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param nums: A list of integers. 8 | * @return: A list of unique permutations. 9 | */ 10 | vector> permuteUnique(vector &nums) { 11 | vector> result; 12 | vector used(nums.size(), false); 13 | vector ans; 14 | 15 | sort(nums.begin(), nums.end()); 16 | permuteUniqueHelper(nums, &used, &ans, &result); 17 | return result; 18 | } 19 | 20 | void permuteUniqueHelper(const vector &A, vector *used, 21 | vector *ans, vector> *result) { 22 | if (ans->size() == A.size()) { 23 | result->emplace_back(*ans); 24 | return; 25 | } 26 | 27 | for (size_t i = 0; i < A.size(); ++i) { 28 | if ((*used)[i] || (i != 0 && A[i - 1] == A[i] && !(*used)[i - 1])) { 29 | continue; 30 | } 31 | (*used)[i] = true; 32 | ans->emplace_back(A[i]); 33 | permuteUniqueHelper(A, used, ans, result); 34 | ans->pop_back(); 35 | (*used)[i] = false; 36 | } 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /C++/merge-sorted-array-ii.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(m + n) 2 | // Space: O(1) 3 | 4 | // If size of A >>>> size of B, you can use binary search to insert the smaller array. 5 | // It only cost O(mlogn) comparisons instead of O(n), much better. 6 | class Solution { 7 | public: 8 | /** 9 | * @param A and B: sorted integer array A and B. 10 | * @return: A new sorted integer array 11 | */ 12 | vector mergeSortedArray(vector &A, vector &B) { 13 | vector C(A.size() + B.size()); 14 | 15 | int i = 0; 16 | int j = 0; 17 | 18 | // Stop comparing while one of array ends. 19 | // Smaller one has high possibility to end first. 20 | while (i < A.size() && j < B.size()) { 21 | if (A[i] >= B[j]) { 22 | C[i + j] = B[j]; 23 | ++j; 24 | } else { 25 | C[i + j] = A[i]; 26 | ++i; 27 | } 28 | } 29 | 30 | // Copy the remaining elements to the new array. 31 | if (i < A.size()) { 32 | copy(A.cbegin() + i, A.cend(), C.begin() + i + j); 33 | } else if (j < B.size()) { 34 | copy(B.cbegin() + j, B.cend(), C.begin() + i + j); 35 | } 36 | 37 | return C; 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /C++/powx-n.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(logn) = O(1) 2 | // Space: O(1) 3 | 4 | // Iterative solution. 5 | class Solution { 6 | public: 7 | /** 8 | * @param x the base number 9 | * @param n the power number 10 | * @return the result 11 | */ 12 | double myPow(double x, int n) { 13 | double result = 1; 14 | long long abs_n = abs(static_cast(n)); 15 | while (abs_n > 0) { 16 | if (abs_n & 1) { 17 | result *= x; 18 | } 19 | abs_n >>= 1; 20 | x *= x; 21 | } 22 | return n < 0 ? 1 / result : result; 23 | } 24 | }; 25 | 26 | // Time: O(logn) = O(1) 27 | // Space: O(logn) = O(1) 28 | // Recursive solution. 29 | class Solution2 { 30 | public: 31 | /** 32 | * @param x the base number 33 | * @param n the power number 34 | * @return the resultult 35 | */ 36 | double myPow(double x, int n) { 37 | if (n < 0 && n != -n) { 38 | return 1.0 / myPow(x, -n); 39 | } 40 | if (n == 0) { 41 | return 1; 42 | } 43 | double v = myPow(x, n / 2); 44 | if (n % 2 == 0) { 45 | return v * v; 46 | } else { 47 | return v * v * x; 48 | } 49 | } 50 | }; 51 | -------------------------------------------------------------------------------- /C++/maximal-square.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(m * n) 2 | // Space: O(n) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param matrix: a matrix of 0 and 1 8 | * @return: an integer 9 | */ 10 | int maxSquare(vector > &matrix) { 11 | if (matrix.empty()) { 12 | return 0; 13 | } 14 | const int m = matrix.size(), n = matrix[0].size(); 15 | vector> size(2, vector(n, 0)); 16 | int max_size = 0; 17 | 18 | for (int j = 0; j < n; ++j) { 19 | size[0][j] = matrix[0][j]; 20 | max_size = max(max_size, size[0][j]); 21 | } 22 | for (int i = 1; i < m; ++i) { 23 | size[i % 2][0] = matrix[i][0]; 24 | for (int j = 1; j < n; ++j) { 25 | if (matrix[i][j] == 1) { 26 | size[i % 2][j] = min(size[i % 2][j - 1], 27 | min(size[(i - 1) % 2][j], 28 | size[(i - 1) % 2][j - 1])) + 1; 29 | max_size = max(max_size, size[i % 2][j]); 30 | } else { 31 | size[i % 2][j] = 0; 32 | } 33 | } 34 | } 35 | return max_size * max_size; 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /C++/n-queens-ii.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n * n!) 2 | // Space: O(n) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * Calculate the total number of distinct N-Queen solutions. 8 | * @param n: The number of queens. 9 | * @return: The total number of distinct solutions. 10 | */ 11 | int totalNQueens(int n) { 12 | vector placement(n); 13 | return n_queens_helper(n, 0, &placement); 14 | } 15 | 16 | bool is_feasible(const vector& col_placement, int row) { 17 | for (int i = 0; i < row; ++i) { 18 | int diff = abs(col_placement[i] - col_placement[row]); 19 | if (diff == 0 || diff == row - i) { 20 | return false; 21 | } 22 | } 23 | return true; 24 | } 25 | 26 | int n_queens_helper(int n, int row, vector* col_placement) { 27 | if (row == n) { 28 | return 1; 29 | } else { 30 | int sum = 0; 31 | for (int col = 0; col < n; ++col) { 32 | (*col_placement)[row] = col; 33 | if (is_feasible(*col_placement, row)) { 34 | sum += n_queens_helper(n, row + 1, col_placement); 35 | } 36 | } 37 | return sum; 38 | } 39 | } 40 | }; 41 | 42 | -------------------------------------------------------------------------------- /C++/lowest-common-ancestor.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(h) 3 | 4 | /** 5 | * Definition of TreeNode: 6 | * class TreeNode { 7 | * public: 8 | * int val; 9 | * TreeNode *left, *right; 10 | * TreeNode(int val) { 11 | * this->val = val; 12 | * this->left = this->right = NULL; 13 | * } 14 | * } 15 | */ 16 | class Solution { 17 | public: 18 | /** 19 | * @param root: The root of the binary search tree. 20 | * @param A and B: two nodes in a Binary. 21 | * @return: Return the least common ancestor(LCA) of the two nodes. 22 | */ 23 | TreeNode *lowestCommonAncestor(TreeNode *root, TreeNode *A, TreeNode *B) { 24 | if (root == nullptr || root == A || root == B) { 25 | return root; 26 | } 27 | TreeNode *left = lowestCommonAncestor(root->left, A, B); 28 | TreeNode *right = lowestCommonAncestor(root->right, A, B); 29 | // 1. If the current subtree contains both A and B, 30 | // return their LCA. 31 | // 2. If only one of them is in that subtree, 32 | // return that one of them. 33 | // 3. If neither of them is in that subtree, 34 | // return the node of that subtree. 35 | return left ? (right ? root : left) : right; 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /C++/clone-graph.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(|V| + |E|) 2 | // Space: O(|V|) 3 | 4 | /** 5 | * Definition for undirected graph. 6 | * struct UndirectedGraphNode { 7 | * int label; 8 | * vector neighbors; 9 | * UndirectedGraphNode(int x) : label(x) {}; 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | /** 15 | * @param node: A undirected graph node 16 | * @return: A undirected graph node 17 | */ 18 | UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) { 19 | if (!node) { 20 | return nullptr; 21 | } 22 | unordered_map copied; 23 | copied[node] = new UndirectedGraphNode(node->label); 24 | queue q; 25 | q.emplace(node); 26 | while (!q.empty()) { 27 | auto node = q.front(); 28 | q.pop(); 29 | 30 | for (const auto& n : node->neighbors) { 31 | if (copied.find(n) == copied.end()) { 32 | copied[n] = new UndirectedGraphNode(n->label); 33 | q.emplace(n); 34 | } 35 | 36 | copied[node]->neighbors.emplace_back(copied[n]); 37 | } 38 | } 39 | 40 | return copied[node]; 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /C++/longest-common-substring.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(m * n) 2 | // Space: O(min(m, n)) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param A, B: Two string. 8 | * @return: the length of the longest common substring. 9 | */ 10 | int longestCommonSubstring(string &A, string &B) { 11 | if (A.length() < B.length()) { 12 | return longestCommonSubstring(B, A); 13 | } 14 | 15 | // table[i][j] means the longest length of common substring 16 | // of A which ends with A[i - 1] and B which ends with B[j - 1]. 17 | vector> table(2, vector(A.length() + 1, 0)); 18 | int longest = 0; 19 | 20 | // if A[i - 1] != B[j - 1]: 21 | // table[i][j] = 0 22 | // if A[i - 1] == B[j - 1]: 23 | // table[i][j] = table[i - 1][j - 1] + 1 24 | for (int i = 1; i < A.length() + 1; ++i) { 25 | for (int j = 1; j < B.length() + 1; ++j) { 26 | if (A[i - 1] != B[j - 1]) { 27 | table[i % 2][j] = 0; 28 | } else { 29 | table[i % 2][j] = table[(i - 1) % 2][j - 1] + 1; 30 | longest = max(longest, table[i % 2][j]); 31 | } 32 | } 33 | } 34 | 35 | return longest; 36 | } 37 | }; 38 | 39 | -------------------------------------------------------------------------------- /C++/segment-tree-query-ii.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(h) 2 | // Space: O(h) 3 | 4 | /** 5 | * Definition of SegmentTreeNode: 6 | * class SegmentTreeNode { 7 | * public: 8 | * int start, end, count; 9 | * SegmentTreeNode *left, *right; 10 | * SegmentTreeNode(int start, int end, int count) { 11 | * this->start = start; 12 | * this->end = end; 13 | * this->count = count; 14 | * this->left = this->right = NULL; 15 | * } 16 | * } 17 | */ 18 | class Solution { 19 | public: 20 | /** 21 | *@param root, start, end: The root of segment tree and 22 | * an segment / interval 23 | *@return: The count number in the interval [start, end] 24 | */ 25 | int query(SegmentTreeNode *root, int start, int end) { 26 | // Out of range. 27 | if (root == nullptr || root->start > end || root->end < start) { 28 | return 0; 29 | } 30 | 31 | // Current segment is totally within range [start, end] 32 | if (root->start >= start && root->end <= end) { 33 | return root->count; 34 | } 35 | 36 | int left = query(root->left, start, end); 37 | int right = query(root->right, start, end); 38 | 39 | // Find max in the children. 40 | return left + right; 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /C++/segment-tree-query.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(h) 2 | // Space: O(h) 3 | 4 | /** 5 | * Definition of SegmentTreeNode: 6 | * class SegmentTreeNode { 7 | * public: 8 | * int start, end, max; 9 | * SegmentTreeNode *left, *right; 10 | * SegmentTreeNode(int start, int end, int max) { 11 | * this->start = start; 12 | * this->end = end; 13 | * this->max = max; 14 | * this->left = this->right = NULL; 15 | * } 16 | * } 17 | */ 18 | class Solution { 19 | public: 20 | /** 21 | *@param root, start, end: The root of segment tree and 22 | * an segment / interval 23 | *@return: The maximum number in the interval [start, end] 24 | */ 25 | int query(SegmentTreeNode *root, int start, int end) { 26 | // Out of range. 27 | if (root == nullptr || root->start > end || root->end < start) { 28 | return INT_MIN; 29 | } 30 | 31 | // Current segment is totally within range [start, end] 32 | if (root->start >= start && root->end <= end) { 33 | return root->max; 34 | } 35 | 36 | int left = query(root->left, start, end); 37 | int right = query(root->right, start, end); 38 | 39 | // Find max in the children. 40 | return max(left, right); 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /C++/segment-tree-build.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(h) = O(logn) 3 | 4 | /** 5 | * Definition of SegmentTreeNode: 6 | * class SegmentTreeNode { 7 | * public: 8 | * int start, end; 9 | * SegmentTreeNode *left, *right; 10 | * SegmentTreeNode(int start, int end) { 11 | * this->start = start, this->end = end; 12 | * this->left = this->right = NULL; 13 | * } 14 | * } 15 | */ 16 | class Solution { 17 | public: 18 | /** 19 | *@param start, end: Denote an segment / interval 20 | *@return: The root of Segment Tree 21 | */ 22 | SegmentTreeNode * build(int start, int end) { 23 | if (start > end) { 24 | return nullptr; 25 | } 26 | 27 | // The root's start and end is given by build method. 28 | SegmentTreeNode *root = new SegmentTreeNode(start, end); 29 | 30 | // If start equals to end, there will be no children for this node. 31 | if (start == end) { 32 | return root; 33 | } 34 | 35 | // Left child: start=A.left, end=(A.left + A.right) / 2. 36 | root->left = build(start, (start + end) / 2); 37 | 38 | // Right child: start=(A.left + A.right) / 2 + 1, end=A.right. 39 | root->right = build((start + end) / 2 + 1, end); 40 | 41 | return root; 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /C++/triangle.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(n) 3 | 4 | #include 5 | #include 6 | 7 | using std::min; 8 | using std::vector; 9 | 10 | class Solution { 11 | public: 12 | /** 13 | * @param triangle: a list of lists of integers. 14 | * @return: An integer, minimum path sum. 15 | */ 16 | int minimumTotal(vector> &triangle) { 17 | // for empty input 18 | if (triangle.empty()) { 19 | return 0; 20 | } 21 | 22 | // Stores the minimum path sum of triangle[i - 1]. 23 | vector prev_row(triangle.front()); 24 | for (size_t i = 1; i < triangle.size(); ++i) { 25 | // Stores the minimum path sum of triangle[i]. 26 | vector curr_row(triangle[i]); 27 | curr_row.front() += prev_row.front(); // For the first element. 28 | for (size_t j = 1; j < curr_row.size() - 1; ++j) { 29 | curr_row[j] += min(prev_row[j - 1], prev_row[j]); 30 | } 31 | curr_row.back() += prev_row.back(); // For the last element. 32 | 33 | prev_row.swap(curr_row); 34 | } 35 | return *min_element(prev_row.cbegin(), prev_row.cend()); 36 | } 37 | }; 38 | 39 | -------------------------------------------------------------------------------- /Python/find-peak-element.py: -------------------------------------------------------------------------------- 1 | # Time: O(logn) 2 | # Space: O(1) 3 | # 4 | # There is an integer array which has the following features: 5 | # 6 | # * The numbers in adjacent positions are different. 7 | # 8 | # * A[0] < A[1] && A[A.length - 2] > A[A.length - 1]. 9 | # 10 | # We define a position P is a peek if A[P] > A[P-1] && A[P] > A[P+1]. 11 | # 12 | # Find a peak element in this array. Return the index of the peak. 13 | # 14 | # Note 15 | # The array may contains multiple peeks, find any of them. 16 | # 17 | # Example 18 | # [1, 2, 1, 3, 4, 5, 7, 6] 19 | # 20 | # return index 1 (which is number 2) or 6 (which is number 7) 21 | # 22 | # Challenge 23 | # Time complexity O(logN) 24 | # 25 | 26 | class Solution: 27 | #@param A: An integers list. 28 | #@return: return any of peek positions. 29 | def findPeak(self, A): 30 | low, high = 0, len(A) - 1 31 | 32 | while low < high: 33 | mid = low + (high - low) / 2 34 | if (mid == 0 or A[mid - 1] <= A[mid]) and \ 35 | (mid == len(A) - 1 or A[mid + 1] <= A[mid]): 36 | return mid 37 | elif mid > 0 and A[mid - 1] > A[mid]: 38 | high = mid - 1 39 | else: 40 | low = mid + 1 41 | mid = low + (high - low) / 2 42 | 43 | return low 44 | -------------------------------------------------------------------------------- /C++/binary-representation.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(1) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | *@param n: Given a decimal number that is passed in as a string 8 | *@return: A string 9 | */ 10 | string binaryRepresentation(string n) { 11 | int int_part = stoi(n.substr(0, n.find('.')); 12 | double dec_part = stod(n.substr(n.find('.'))); 13 | string int_str = ""; 14 | string dec_str = ""; 15 | 16 | if (int_part == 0) { 17 | int_str.push_back('0'); 18 | } 19 | 20 | while (int_part > 0) { 21 | int c = int_part % 2; 22 | int_str.push_back('0' + c); 23 | int_part = int_part >> 1; 24 | } 25 | reverse(int_str.begin(), int_str.end()); 26 | 27 | while (dec_part > 0.0) { 28 | if (dec_str.length() > 32) { 29 | return "ERROR"; 30 | } 31 | double remain = dec_part * 2; 32 | if (remain >= 1.0) { 33 | dec_str.push_back('1'); 34 | dec_part = remain - 1.0; 35 | } 36 | else { 37 | dec_str.push_back('0'); 38 | dec_part = remain; 39 | } 40 | } 41 | return dec_str.length() > 0? int_str + "." + dec_str : int_str; 42 | } 43 | }; 44 | 45 | -------------------------------------------------------------------------------- /C++/combination-sum-ii.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(k * C(n, k)), k is max length of combination 2 | // Space: O(k) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param num: Given the candidate numbers 8 | * @param target: Given the target number 9 | * @return: All the combinations that sum to target 10 | */ 11 | vector> combinationSum2(vector &num, int target) { 12 | sort(num.begin(), num.end()); 13 | vector> ans; 14 | vector v; 15 | combinationSum2Helper(num, target, 0, v, ans); 16 | return ans; 17 | } 18 | 19 | private: 20 | void combinationSum2Helper(vector& num, int gap, int begin, 21 | vector& v,vector> &ans) { 22 | if (gap == 0) { 23 | ans.emplace_back(v); 24 | return; 25 | } 26 | 27 | for (size_t i = begin; i < num.size() && num[i] <= gap; ++i) { 28 | if ( i == begin || num[i] != num[i - 1]) { // Skip duplicates. 29 | // Each same element could be chosen only once 30 | // with the same previous nums. 31 | v.emplace_back(num[i]); 32 | combinationSum2Helper(num, gap - num[i], i + 1, v, ans); 33 | v.pop_back(); 34 | } 35 | } 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /C++/permutation-sequence.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n^2) 2 | // Space: O(n) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param n: n 8 | * @param k: the kth permutation 9 | * @return: return the k-th permutation 10 | */ 11 | string getPermutation(int n, int k) { 12 | vector nums; 13 | int total = 1; 14 | for (int i = 1; i <= n; ++i) { 15 | nums.emplace_back(i); 16 | total *= i; 17 | } 18 | 19 | // Cantor Ordering: 20 | // Construct the k-th permutation with a list of n numbers 21 | // Idea: group all permutations according to their first number (so n groups, each of 22 | // (n - 1)! numbers), find the group where the k-th permutation belongs, remove the common 23 | // first number from the list and append it to the resulting string, and iteratively 24 | // construct the (((k - 1) % (n - 1)!) + 1)-th permutation with the remaining n-1 numbers 25 | int group = total; 26 | stringstream output; 27 | while (n > 0) { 28 | group /= n; 29 | int idx = (k - 1) / group; 30 | output << nums[idx]; 31 | nums.erase(nums.begin() + idx); 32 | k = (k - 1) % group + 1; 33 | --n; 34 | } 35 | 36 | return output.str(); 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /C++/print-numbers-by-recursion.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(n) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param n: An integer. 8 | * return : An array storing 1 to the largest number with n digits. 9 | */ 10 | vector numbersByRecursion(int n) { 11 | vector result; 12 | numbersByRecursionHelper(0, n, result); 13 | return result; 14 | } 15 | 16 | // Construct the numbers by the current digit count. 17 | void numbersByRecursionHelper(int depth, int n, vector& result) { 18 | if (depth == n) { 19 | return; 20 | } 21 | 22 | if (depth == 0) { // Initiate the result. 23 | for (size_t d = 1; d <= 9; ++d) { 24 | result.emplace_back(d); 25 | } 26 | } else { // Construct the numbers by the previous result. 27 | const size_t count = result.size(); 28 | for (size_t d = 1; d <= 9; ++d) { 29 | result.emplace_back(d * pow(10, depth)); 30 | for (size_t i = 0; i < count; ++i) { 31 | result.emplace_back(result[i] + d * pow(10, depth)); 32 | } 33 | } 34 | } 35 | // Construct the numbers in the next depth. 36 | numbersByRecursionHelper(depth + 1, n, result); 37 | } 38 | 39 | }; 40 | -------------------------------------------------------------------------------- /C++/longest-common-subsequence.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(m * n) 2 | // Space: O(min(m, n)) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param A, B: Two strings. 8 | * @return: The length of longest common subsequence of A and B. 9 | */ 10 | int longestCommonSubsequence(string A, string B) { 11 | if (A.length() < B.length()) { 12 | return longestCommonSubsequence(B, A); 13 | } 14 | 15 | // table[i][j] means the longest length of common subsequence 16 | // of A[0 : i] and B[0 : j]. 17 | vector> table(2, vector(A.length() + 1, 0)); 18 | 19 | // if A[i - 1] != B[j - 1]: 20 | // table[i][j] = max(table[i - 1][j], table[i][j - 1]) 21 | // if A[i - 1] == B[j - 1]: 22 | // table[i][j] = table[i - 1][j - 1] + 1 23 | for (int i = 1; i < A.length() + 1; ++i) { 24 | for (int j = 1; j < B.length() + 1; ++j) { 25 | if (A[i - 1] != B[j - 1]) { 26 | table[i % 2][j] = max(table[(i - 1) % 2][j], 27 | table[i % 2][j - 1]); 28 | } else { 29 | table[i % 2][j] = table[(i - 1) % 2][j - 1] + 1; 30 | } 31 | } 32 | } 33 | 34 | return table[A.length() % 2][B.length()]; 35 | } 36 | }; 37 | 38 | -------------------------------------------------------------------------------- /C++/reverse-linked-list-ii.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | /** 5 | * Definition of singly-linked-list: 6 | * 7 | * class ListNode { 8 | * public: 9 | * int val; 10 | * ListNode *next; 11 | * ListNode(int val) { 12 | * this->val = val; 13 | * this->next = NULL; 14 | * } 15 | * } 16 | */ 17 | class Solution { 18 | public: 19 | /** 20 | * @param head: The head of linked list. 21 | * @param m: The start position need to reverse. 22 | * @param n: The end position need to reverse. 23 | * @return: The new head of partial reversed linked list. 24 | */ 25 | ListNode *reverseBetween(ListNode *head, int m, int n) { 26 | ListNode dummy{0}; 27 | dummy.next = head; 28 | 29 | auto prev = &dummy; 30 | for (int i = 0; i < m - 1; ++i) { 31 | prev = prev->next; 32 | } 33 | 34 | auto head2 = prev; 35 | prev = prev->next; 36 | auto curr = prev->next; 37 | for (int i = m; i < n; ++i) { 38 | prev->next = curr->next; // Remove curr from the list. 39 | curr->next = head2->next; // Add curr to the head. 40 | head2->next = curr; // Add curr to the head. 41 | curr = prev->next; // Get next curr. 42 | } 43 | 44 | return dummy.next; 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /C++/binary-search-tree-iterator.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(1), amortized 2 | // Space: O(h) 3 | 4 | /** 5 | * Definition of TreeNode: 6 | * class TreeNode { 7 | * public: 8 | * int val; 9 | * TreeNode *left, *right; 10 | * TreeNode(int val) { 11 | * this->val = val; 12 | * this->left = this->right = NULL; 13 | * } 14 | * } 15 | * Example of iterate a tree: 16 | * Solution iterator = Solution(root); 17 | * while (iterator.hasNext()) { 18 | * TreeNode * node = iterator.next(); 19 | * do something for node 20 | */ 21 | class Solution { 22 | public: 23 | //@param root: The root of binary tree. 24 | Solution(TreeNode *root) { 25 | curr = root; 26 | } 27 | 28 | //@return: True if there has next node, or false 29 | bool hasNext() { 30 | return !s.empty() || curr != nullptr; 31 | } 32 | 33 | //@return: return next node 34 | TreeNode* next() { 35 | // Go to left most descendant. 36 | while (curr != nullptr) { 37 | s.emplace(curr); 38 | curr = curr->left; 39 | } 40 | curr = s.top(); // Left most node. 41 | s.pop(); 42 | 43 | TreeNode *node = curr; 44 | curr = curr->right; // Visit right child. 45 | 46 | return node; 47 | } 48 | private: 49 | stack s; 50 | TreeNode *curr; 51 | }; 52 | 53 | -------------------------------------------------------------------------------- /C++/find-minimum-in-rotated-sorted-array.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(logn) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param num: a rotated sorted array 8 | * @return: the minimum number in the array 9 | */ 10 | int findMin(vector &num) { 11 | int left = 0, right = num.size() - 1; 12 | const auto target = num.back(); 13 | 14 | while (left <= right) { 15 | const auto mid = left + (right - left) / 2; 16 | if (num[mid] <= target) { 17 | right = mid - 1; 18 | } else { 19 | left = mid + 1; 20 | } 21 | } 22 | 23 | return num[left]; 24 | } 25 | }; 26 | 27 | class Solution2 { 28 | public: 29 | /** 30 | * @param num: a rotated sorted array 31 | * @return: the minimum number in the array 32 | */ 33 | int findMin(vector &num) { 34 | int left = 0, right = num.size() - 1; 35 | 36 | // Find min left s.t. num[left] < num[left']. 37 | while (left < right && num[left] >= num[right]) { 38 | const auto mid = left + (right - left) / 2; 39 | if (num[mid] < num[left]) { 40 | right = mid; 41 | } else { 42 | left = mid + 1; 43 | } 44 | } 45 | 46 | return num[left]; 47 | } 48 | }; 49 | 50 | -------------------------------------------------------------------------------- /C++/binary-tree-path-sum.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(h) 3 | 4 | /** 5 | * Definition of TreeNode: 6 | * class TreeNode { 7 | * public: 8 | * int val; 9 | * TreeNode *left, *right; 10 | * TreeNode(int val) { 11 | * this->val = val; 12 | * this->left = this->right = NULL; 13 | * } 14 | * } 15 | */ 16 | class Solution { 17 | public: 18 | /** 19 | * @param root the root of binary tree 20 | * @param target an integer 21 | * @return all valid paths 22 | */ 23 | vector> binaryTreePathSum(TreeNode *root, int target) { 24 | vector> res; 25 | vector cur; 26 | binaryTreePathHelper(root, target, &cur, &res); 27 | return res; 28 | } 29 | 30 | void binaryTreePathHelper(const TreeNode *root, const int target, 31 | vector *cur, vector> *res) { 32 | if (!root) { 33 | return; 34 | } 35 | 36 | cur->emplace_back(root->val); 37 | if (!root->left && !root->right && root->val == target) { 38 | res->emplace_back(*cur); 39 | } else { 40 | binaryTreePathHelper(root->left, target - root->val, cur, res); 41 | binaryTreePathHelper(root->right, target - root->val, cur, res); 42 | } 43 | cur->pop_back(); 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /C++/intersection-of-two-linked-lists.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(m + n) 2 | // Space: O(1) 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode(int x) : val(x), next(NULL) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | /** 15 | * @param headA: the first list 16 | * @param headB: the second list 17 | * @return: a ListNode 18 | */ 19 | ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { 20 | auto currA = headA, currB = headB; 21 | ListNode *begin = nullptr, *tailA = nullptr, *tailB = nullptr; 22 | while (currA && currB) { 23 | if (currA == currB) { 24 | begin = currA; 25 | break; 26 | } 27 | 28 | if (currA->next) { 29 | currA = currA->next; 30 | } else if (!tailA) { 31 | tailA = currA; 32 | currA = headB; 33 | } else { 34 | break; 35 | } 36 | 37 | if (currB->next) { 38 | currB = currB->next; 39 | } else if (!tailB) { 40 | tailB = currB; 41 | currB = headA; 42 | } else { 43 | break; 44 | } 45 | } 46 | 47 | return begin; 48 | } 49 | }; 50 | -------------------------------------------------------------------------------- /Python/backpack.py: -------------------------------------------------------------------------------- 1 | # Time: O(n*m) 2 | # Space: O(m) 3 | # 4 | # Given n items with size A[i], an integer m denotes the size of a backpack. 5 | # How full you can fill this backpack? 6 | # 7 | # Note 8 | # You can not divide any item into small pieces. 9 | # 10 | # Example 11 | # If we have 4 items with size [2, 3, 5, 7], the backpack size is 11, we can select 2, 3 and 5, 12 | # so that the max size we can fill this backpack is 10. If the backpack size is 12. 13 | # we can select [2, 3, 7] so that we can fulfill the backpack. 14 | # 15 | # You function should return the max size we can fill in the given backpack. 16 | # 17 | class Solution: 18 | # @param m: An integer m denotes the size of a backpack 19 | # @param A: Given n items with size A[i] 20 | # @return: The maximum size 21 | def backPack(self, m, A): 22 | # write your code here 23 | d = [[False for j in xrange(m+1)] for i in xrange(2)] 24 | result = 0 25 | d[0][0] = True 26 | 27 | for i in xrange(1, len(A) + 1): 28 | d[i%2][0] = True 29 | for j in xrange(1, m+1): 30 | d[i%2][j] = d[(i-1)%2][j] 31 | if j >= A[i-1]: 32 | d[i%2][j] = d[(i-1)%2][j] or d[(i-1)%2][j-A[i-1]] 33 | if d[i%2][j]: 34 | result = max(result, j) 35 | 36 | return result 37 | -------------------------------------------------------------------------------- /C++/lru-cache.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(1), per operation. 2 | // Space: O(k), k is the capacity of cache. 3 | 4 | #include 5 | 6 | class LRUCache { 7 | public: 8 | LRUCache(int capacity) : capa_(capacity) { 9 | } 10 | 11 | int get(int key) { 12 | if (map_.find(key) != map_.end()) { 13 | // It key exists, update it. 14 | const auto value = map_[key]->second; 15 | update(key, value); 16 | return value; 17 | } else { 18 | return -1; 19 | } 20 | } 21 | 22 | void set(int key, int value) { 23 | // If cache is full while inserting, remove the last one. 24 | if (map_.find(key) == map_.end() && list_.size() == capa_) { 25 | auto del = list_.back(); list_.pop_back(); 26 | map_.erase(del.first); 27 | } 28 | update(key, value); 29 | } 30 | 31 | private: 32 | list> list_; // key, value 33 | unordered_map>::iterator> map_; // key, list iterator 34 | int capa_; 35 | 36 | // Update (key, iterator of (key, value)) pair 37 | void update(int key, int value) { 38 | auto it = map_.find(key); 39 | if (it != map_.end()) { 40 | list_.erase(it->second); 41 | } 42 | list_.emplace_front(key, value); 43 | map_[key] = list_.begin(); 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /C++/maximum-subarray-ii.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(n) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param nums: A list of integers 8 | * @return: An integer denotes the sum of max two non-overlapping subarrays 9 | */ 10 | int maxTwoSubArrays(vector nums) { 11 | int n = nums.size(); 12 | vector max_LR(n); 13 | vector max_RL(n); 14 | 15 | // Compute the max sum of subarray from left to right. 16 | int max_LR_sum = INT_MIN, LR_sum = 0; 17 | for (int i = 0; i < n; ++i) { 18 | LR_sum += nums[i]; 19 | max_LR_sum = max(max_LR_sum, LR_sum); 20 | max_LR[i] = max_LR_sum; 21 | LR_sum = max(LR_sum, 0); 22 | } 23 | 24 | // Compute the max sum of subarray from right to left. 25 | int max_RL_sum = INT_MIN, RL_sum = 0; 26 | for (int i = n - 1; i >= 0; --i) { 27 | RL_sum += nums[i]; 28 | max_RL_sum = max(max_RL_sum, RL_sum); 29 | max_RL[i] = max_RL_sum; 30 | RL_sum = max(RL_sum, 0); 31 | } 32 | 33 | // Compute the max sum of two non-overlapping subarrays. 34 | int max_sum = INT_MIN; 35 | for (int i = 0; i < n - 1; ++i) { 36 | max_sum = max(max_sum, max_LR[i] + max_RL[i+1]); 37 | } 38 | 39 | return max_sum; 40 | } 41 | }; 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /C++/reverse-nodes-in-k-group.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode(int x) : val(x), next(NULL) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | /** 15 | * @param head a ListNode 16 | * @param k an integer 17 | * @return a ListNode 18 | */ 19 | ListNode *reverseKGroup(ListNode *head, int k) { 20 | ListNode dummy{0}; 21 | dummy.next = head; 22 | auto curr = head, curr_dummy = &dummy; 23 | int length = 0; 24 | 25 | while (curr) { 26 | ListNode *next_curr = curr->next; 27 | length = (length + 1) % k; 28 | 29 | if (length == 0) { 30 | ListNode *next_dummy = curr_dummy->next; 31 | reverse(&curr_dummy, curr->next); 32 | curr_dummy = next_dummy; 33 | } 34 | curr = next_curr; 35 | } 36 | return dummy.next; 37 | } 38 | 39 | void reverse(ListNode **begin, const ListNode *end) { 40 | auto first = (*begin)->next, curr = first->next; 41 | 42 | while (curr != end) { 43 | first->next = curr->next; 44 | curr->next = (*begin)->next; 45 | (*begin)->next = curr; 46 | curr = first->next; 47 | } 48 | } 49 | }; 50 | -------------------------------------------------------------------------------- /C++/backpack.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(m * n) 2 | // Space: O(m) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param m: An integer m denotes the size of a backpack 8 | * @param A: Given n items with size A[i] 9 | * @return: The maximum size 10 | */ 11 | int backPack(int m, vector A) { 12 | // table[i][j] denotes whether using the first i elements 13 | // could fulfill size j. 14 | vector> table(2, vector(m + 1, false)); 15 | int max_size = 0; 16 | table[0][0] = true; 17 | 18 | for (int i = 1; i <= A.size(); ++i) { 19 | table[i % 2][0] = true; 20 | for (int j = 1; j <= m; ++j) { 21 | // If first i - 1 elements could fulfill the backpack, then 22 | // first i elements would also do. 23 | table[i % 2][j] = table[(i - 1) % 2][j]; 24 | 25 | // Using the ith element to fulfill the backpack. 26 | if (j >= A[i - 1]) { 27 | table[i % 2][j] = table[i % 2][j] 28 | || table[(i - 1) % 2][j - A[i - 1]]; 29 | } 30 | 31 | // If it fulfills size j, update max size. 32 | if (table[i % 2][j]) { 33 | max_size = max(max_size, j); 34 | } 35 | } 36 | } 37 | 38 | return max_size; 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /C++/binary-tree-level-order-traversal.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(n) 3 | 4 | /** 5 | * Definition of TreeNode: 6 | * class TreeNode { 7 | * public: 8 | * int val; 9 | * TreeNode *left, *right; 10 | * TreeNode(int val) { 11 | * this->val = val; 12 | * this->left = this->right = NULL; 13 | * } 14 | * } 15 | */ 16 | 17 | class Solution { 18 | /** 19 | * @param root: The root of binary tree. 20 | * @return: Level order a list of lists of integer 21 | */ 22 | public: 23 | vector> levelOrder(TreeNode *root) { 24 | vector> result; 25 | queue que; 26 | 27 | if (root != nullptr) { 28 | que.emplace(root); 29 | } 30 | 31 | while (!que.empty()) { 32 | vector level; 33 | int size = que.size(); 34 | for (int i = 0; i < size; i++) { 35 | auto *front = que.front(); 36 | que.pop(); 37 | level.emplace_back(front->val); 38 | if (front->left != nullptr) { 39 | que.emplace(front->left); 40 | } 41 | if (front->right != nullptr) { 42 | que.emplace(front->right); 43 | } 44 | } 45 | result.emplace_back(move(level)); 46 | } 47 | 48 | return result; 49 | } 50 | }; 51 | -------------------------------------------------------------------------------- /C++/next-permutation.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param nums: An array of integers 8 | * @return: An array of integers that's next permuation 9 | */ 10 | vector nextPermuation(vector &nums) { 11 | int k = -1, l = 0; 12 | 13 | // Find the last index k before the decreasing sequence. 14 | for (int i = 0; i < nums.size() - 1; ++i) { 15 | if (nums[i] < nums[i + 1]) { 16 | k = i; 17 | } 18 | } 19 | 20 | if (k >= 0) { 21 | // Find the smallest number which is larger than the value of the index k, 22 | // and swap the values. 23 | for (int i = k + 1; i < nums.size(); ++i) { 24 | if (nums[i] > nums[k]) { 25 | l = i; 26 | } 27 | } 28 | swap(nums[k], nums[l]); 29 | } 30 | 31 | // Reverse the sequence after the index k. 32 | reverse(nums.begin() + k + 1, nums.end()); 33 | 34 | return nums; 35 | } 36 | }; 37 | 38 | class Solution2 { 39 | public: 40 | /** 41 | * @param nums: An array of integers 42 | * @return: An array of integers that's next permuation 43 | */ 44 | vector nextPermuation(vector &nums) { 45 | next_permutation(nums.begin(), nums.end()); 46 | return nums; 47 | } 48 | }; 49 | -------------------------------------------------------------------------------- /C++/palindrome-partitioning.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n * 2^n) 2 | // Space: O(n) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param s: A string 8 | * @return: A list of lists of string 9 | */ 10 | vector> partition(string s) { 11 | vector> result; 12 | vector partition; 13 | PalindromePartitioningHelper(s, 0, &partition, &result); 14 | return result; 15 | } 16 | 17 | void PalindromePartitioningHelper(const string& s, size_t begin, 18 | vector* partition, 19 | vector>* result) { 20 | if (begin == s.size()) { 21 | result->emplace_back(*partition); 22 | return; 23 | } 24 | 25 | for (size_t i = begin + 1; i <= s.size(); ++i) { 26 | string prefix = s.substr(begin, i - begin); 27 | if (IsPalindrome(prefix)) { 28 | partition->emplace_back(prefix); 29 | PalindromePartitioningHelper(s, i, partition, result); 30 | partition->pop_back(); 31 | } 32 | } 33 | } 34 | 35 | bool IsPalindrome(const string& s) { 36 | for (int i = 0, j = s.size() - 1; i < j; ++i, --j) { 37 | if (s[i] != s[j]) { 38 | return false; 39 | } 40 | } 41 | return true; 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /C++/rotate-image.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n^2) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param matrix: A list of lists of integers 8 | * @return: Void 9 | */ 10 | void rotate(vector> &matrix) { 11 | const int n = matrix.size(); 12 | for (int i = 0; i < n / 2; ++i) { 13 | for (int j = i; j < n - 1 - i; ++j) { 14 | int tmp = matrix[i][j]; 15 | matrix[i][j] = matrix[n - 1 - j][i]; 16 | matrix[n - 1- j][i] = matrix[n - 1 - i][n - 1 - j]; 17 | matrix[n - 1 - i][n - 1 - j] = matrix[j][n - 1 - i]; 18 | matrix[j][n - 1 - i] = tmp; 19 | } 20 | } 21 | } 22 | }; 23 | 24 | class Solution2 { 25 | public: 26 | /** 27 | * @param matrix: A list of lists of integers 28 | * @return: Void 29 | */ 30 | void rotate(vector> &matrix) { 31 | const int n = matrix.size(); 32 | // Anti-diagonal mirror. 33 | for (int i = 0; i < n; ++i) { 34 | for (int j = 0; j < n - i; ++j) { 35 | swap(matrix[i][j], matrix[n - 1 - j][n - 1 - i]); 36 | } 37 | } 38 | // Horizontal mirror. 39 | for (int i = 0; i < n / 2; ++i) { 40 | for (int j = 0; j < n; ++j) { 41 | swap(matrix[i][j], matrix[n - 1 - i][j]); 42 | } 43 | } 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /C++/insert-interval.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | /** 5 | * Definition of Interval: 6 | * classs Interval { 7 | * int start, end; 8 | * Interval(int start, int end) { 9 | * this->start = start; 10 | * this->end = end; 11 | * } 12 | */ 13 | class Solution { 14 | public: 15 | /** 16 | * Insert newInterval into intervals. 17 | * @param intervals: Sorted interval list. 18 | * @param newInterval: new interval. 19 | * @return: A new interval list. 20 | */ 21 | vector insert(vector &intervals, Interval newInterval) { 22 | size_t i = 0; 23 | vector result; 24 | // Insert intervals appeared before newInterval. 25 | while (i < intervals.size() && newInterval.start > intervals[i].end) { 26 | result.emplace_back(intervals[i++]); 27 | } 28 | 29 | // Merge intervals that overlap with newInterval. 30 | while (i < intervals.size() && newInterval.end >= intervals[i].start) { 31 | newInterval = {min(newInterval.start, intervals[i].start), 32 | max(newInterval.end, intervals[i].end)}; 33 | ++i; 34 | } 35 | result.emplace_back(newInterval); 36 | 37 | // Insert intervals appearing after newInterval. 38 | result.insert(result.end(), intervals.cbegin() + i, intervals.cend()); 39 | return result; 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /C++/binary-tree-maximum-path-sum.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(h) 3 | 4 | /** 5 | * Definition of TreeNode: 6 | * class TreeNode { 7 | * public: 8 | * int val; 9 | * TreeNode *left, *right; 10 | * TreeNode(int val) { 11 | * this->val = val; 12 | * this->left = this->right = NULL; 13 | * } 14 | * } 15 | */ 16 | class Solution { 17 | public: 18 | /** 19 | * @param root: The root of binary tree. 20 | * @return: An integer 21 | */ 22 | int maxPathSum(TreeNode *root) { 23 | maxPathSumHelper(root); 24 | return max_sum_; 25 | } 26 | 27 | // Return max height and update max path sum for each node. 28 | int maxPathSumHelper(TreeNode *root) { 29 | if (root == nullptr) { 30 | return 0; 31 | } 32 | 33 | // Get max descendant sum of children. 34 | // If the sum is less than zero, it can't be the path with max sum. 35 | const auto left = max(0, maxPathSumHelper(root->left)); 36 | const auto right = max(0, maxPathSumHelper(root->right)); 37 | 38 | // "max path sum" equals to: 39 | // "max left descendant sum" -> root -> "max right descendant sum". 40 | max_sum_ = max(max_sum_, root->val + left + right); 41 | 42 | // Return max descendant sum. 43 | return root->val + max(left, right); 44 | } 45 | 46 | private: 47 | int max_sum_ = numeric_limits::min(); 48 | }; 49 | -------------------------------------------------------------------------------- /C++/previous-permutation.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param nums: An array of integers 8 | * @return: An array of integers that's previous permuation 9 | */ 10 | vector previousPermuation(vector &nums) { 11 | int k = -1, l = 0; 12 | 13 | // Find the last index k before the increasing sequence. 14 | for (int i = 0; i < nums.size() - 1; ++i) { 15 | if (nums[i] > nums[i + 1]) { 16 | k = i; 17 | } 18 | } 19 | 20 | if (k >= 0) { 21 | // Find the largest number which is smaller than the value of the index k, 22 | // and swap the values. 23 | for (int i = 0; i < nums.size(); ++i) { 24 | if (nums[i] < nums[k]) { 25 | l = i; 26 | } 27 | } 28 | swap(nums[k], nums[l]); 29 | } 30 | 31 | // Reverse the sequence after the index k. 32 | reverse(nums.begin() + k + 1, nums.end()); 33 | 34 | return nums; 35 | } 36 | }; 37 | 38 | class Solution2 { 39 | public: 40 | /** 41 | * @param nums: An array of integers 42 | * @return: An array of integers that's previous permuation 43 | */ 44 | vector previousPermuation(vector &nums) { 45 | prev_permutation(nums.begin(), nums.end()); 46 | return nums; 47 | } 48 | }; 49 | -------------------------------------------------------------------------------- /C++/longest-consecutive-sequence.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(n) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param nums: A list of integers 8 | * @return an integer 9 | */ 10 | int longestConsecutive(vector &num) { 11 | // unprocessed_entries records the existence of each entry in num. 12 | unordered_set unprocessed_entries; 13 | for (const auto& a : num) { 14 | unprocessed_entries.emplace(a); 15 | } 16 | 17 | int max_interval_size = 0; 18 | while (!unprocessed_entries.empty()) { 19 | int a = *unprocessed_entries.begin(); 20 | unprocessed_entries.erase(a); 21 | 22 | // Finds the lower bound of the largest range containing a. 23 | int lower_bound = a - 1; 24 | while (unprocessed_entries.count(lower_bound)) { 25 | unprocessed_entries.erase(lower_bound); 26 | --lower_bound; 27 | } 28 | 29 | // Finds the upper bound of the largest range containing a. 30 | int upper_bound = a + 1; 31 | while (unprocessed_entries.count(upper_bound)) { 32 | unprocessed_entries.erase(upper_bound); 33 | ++upper_bound; 34 | } 35 | max_interval_size = 36 | max(max_interval_size, upper_bound - lower_bound - 1); 37 | } 38 | return max_interval_size; 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /C++/subsets.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n * 2^n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param S: A set of numbers. 8 | * @return: A list of lists. All valid subsets. 9 | */ 10 | vector> subsets(vector &nums) { 11 | const int size = nums.size(); 12 | const int set_size = 1 << size; 13 | vector> ans; 14 | vector v; 15 | 16 | sort(nums.begin(), nums.end()); 17 | 18 | for (int i = 0; i < set_size; ++i) { 19 | for (int j = 0; j < size; ++j) { 20 | if (i & (1 << j)) { 21 | v.emplace_back(nums[j]); 22 | } 23 | } 24 | ans.emplace_back(v); 25 | v.clear(); 26 | } 27 | 28 | return ans; 29 | } 30 | }; 31 | 32 | // Time: O(n * 2^n) 33 | // Space: O(1) 34 | class Solution2 { 35 | public: 36 | /** 37 | * @param S: A set of numbers. 38 | * @return: A list of lists. All valid subsets. 39 | */ 40 | vector > subsets(vector &nums) { 41 | vector> result(1); 42 | for (size_t i = 0; i < nums.size(); ++i) { 43 | const size_t size = result.size(); 44 | for (size_t j = 0; j < size; ++j) { 45 | result.emplace_back(result[j]); 46 | result.back().emplace_back(nums[i]); 47 | } 48 | } 49 | return result; 50 | } 51 | }; 52 | -------------------------------------------------------------------------------- /C++/triangle-count.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n^2) 2 | // Space: O(1) 3 | 4 | // Two Pointers solution. 5 | class Solution { 6 | public: 7 | /** 8 | * @param S: A list of integers 9 | * @return: An integer 10 | */ 11 | int triangleCount(vector &S) { 12 | sort(S.begin(), S.end()); 13 | const int n = S.size(); 14 | 15 | int count = 0; 16 | for (int k = 2; k < n; ++k) { 17 | int i = 0, j = k - 1; 18 | while (i < j) { // Two Pointers, linear time. 19 | if (S[i] + S[j] <= S[k]) { 20 | ++i; 21 | } else { 22 | count += j - i; 23 | --j; 24 | } 25 | } 26 | } 27 | 28 | return count; 29 | } 30 | }; 31 | 32 | // Time: O(n^2) 33 | // Space: O(1) 34 | class Solution2 { 35 | public: 36 | /** 37 | * @param S: A list of integers 38 | * @return: An integer 39 | */ 40 | int triangleCount(vector &S) { 41 | sort(S.begin(), S.end()); 42 | const int n = S.size(); 43 | 44 | int count = 0; 45 | 46 | for (int i = 0; i < n - 2; ++i) { 47 | int k = i + 2; 48 | for (int j = i + 1; j < n; ++j) { 49 | while (k < n && S[i] + S[j] > S[k]) { 50 | ++k; 51 | } 52 | count += k - j - 1; 53 | } 54 | } 55 | return count; 56 | } 57 | }; 58 | -------------------------------------------------------------------------------- /C++/segment-tree-modify.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(h) 2 | // Space: O(h) 3 | 4 | /** 5 | * Definition of SegmentTreeNode: 6 | * class SegmentTreeNode { 7 | * public: 8 | * int start, end, max; 9 | * SegmentTreeNode *left, *right; 10 | * SegmentTreeNode(int start, int end, int max) { 11 | * this->start = start; 12 | * this->end = end; 13 | * this->max = max; 14 | * this->left = this->right = NULL; 15 | * } 16 | * } 17 | */ 18 | class Solution { 19 | public: 20 | /** 21 | *@param root, index, value: The root of segment tree and 22 | *@ change the node's value with [index, index] to the new given value 23 | *@return: void 24 | */ 25 | void modify(SegmentTreeNode *root, int index, int value) { 26 | // Out of range. 27 | if (root == nullptr || root->start > index || root->end < index) { 28 | return; 29 | } 30 | 31 | // Change the node's value with [index, index] to the new given value. 32 | if (root->start == index && root->end == index) { 33 | root->max = value; 34 | return; 35 | } 36 | 37 | modify(root->left, index, value); 38 | modify(root->right, index, value); 39 | 40 | int left_max = root->left != nullptr? root->left->max : INT_MIN; 41 | int right_max = root->right != nullptr? root->right->max : INT_MIN; 42 | 43 | // Update max. 44 | root->max = max(left_max, right_max); 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /C++/longest-common-prefix.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n * k), k is the length of the common prefix 2 | // Space: O(1) 3 | 4 | // BFS 5 | class Solution { 6 | public: 7 | /** 8 | * @param strs: A list of strings 9 | * @return: The longest common prefix 10 | */ 11 | string longestCommonPrefix(vector &strs) { 12 | if (strs.empty()) { 13 | return ""; 14 | } 15 | 16 | for (int i = 0; i < strs[0].length(); ++i) { 17 | for (const auto& str : strs) { 18 | if (i >= str.length() || str[i] != strs[0][i]) { 19 | return strs[0].substr(0, i); 20 | } 21 | } 22 | } 23 | return strs[0]; 24 | } 25 | }; 26 | 27 | // Time: O(n * l), l is the max length of strings 28 | // Space: O(1) 29 | 30 | // DFS 31 | class Solution2 { 32 | public: 33 | /** 34 | * @param strs: A list of strings 35 | * @return: The longest common prefix 36 | */ 37 | string longestCommonPrefix(vector &strs) { 38 | if (strs.empty()) { 39 | return ""; 40 | } 41 | 42 | auto prefix_len = strs[0].length(); 43 | for (const auto& str : strs) { 44 | auto i = 0; 45 | for (; i < str.length() && i < prefix_len && str[i] == strs[0][i]; ++i); 46 | if (i < prefix_len) { 47 | prefix_len = i; 48 | } 49 | } 50 | return strs[0].substr(0, prefix_len); 51 | } 52 | }; 53 | -------------------------------------------------------------------------------- /C++/simplify-path.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(n) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param path the original path 8 | * @return the simplified path 9 | */ 10 | string simplifyPath(string& path) { 11 | vector names; 12 | vector tokens(move(split(path, '/'))); 13 | for (const auto& token : tokens) { 14 | if (token == ".." && !names.empty()) { 15 | names.pop_back(); 16 | } else if (token != ".." && token != "." && !token.empty()) { 17 | names.emplace_back(token); 18 | } 19 | } 20 | return string("/").append(join(names, '/')); 21 | } 22 | 23 | // Split string by delimitor. 24 | vector split(const string& s, const char delim) { 25 | vector tokens; 26 | stringstream ss(s); 27 | string token; 28 | while (getline(ss, token, delim)) { 29 | tokens.emplace_back(token); 30 | } 31 | return tokens; 32 | } 33 | 34 | // Join strings with delimitor. 35 | string join(const vector& names, const char delim) { 36 | ostringstream ss; 37 | if (!names.empty()) { 38 | const string delim_str(1, delim); 39 | copy(names.cbegin(), prev(names.cend()), 40 | ostream_iterator(ss, delim_str.c_str())); 41 | ss << names.back(); 42 | } 43 | return ss.str(); 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /C++/binary-tree-level-order-traversal-ii.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(n) 3 | 4 | /** 5 | * Definition of TreeNode: 6 | * class TreeNode { 7 | * public: 8 | * int val; 9 | * TreeNode *left, *right; 10 | * TreeNode(int val) { 11 | * this->val = val; 12 | * this->left = this->right = NULL; 13 | * } 14 | * } 15 | */ 16 | 17 | 18 | class Solution { 19 | /** 20 | * @param root : The root of binary tree. 21 | * @return : buttom-up level order a list of lists of integer 22 | */ 23 | public: 24 | vector> levelOrderBottom(TreeNode *root) { 25 | vector> result; 26 | queue que; 27 | 28 | if (root != nullptr) { 29 | que.emplace(root); 30 | } 31 | 32 | while (!que.empty()) { 33 | vector level; 34 | int size = que.size(); 35 | for (int i = 0; i < size; i++) { 36 | auto *front = que.front(); 37 | que.pop(); 38 | level.emplace_back(front->val); 39 | if (front->left != nullptr) { 40 | que.emplace(front->left); 41 | } 42 | if (front->right != nullptr) { 43 | que.emplace(front->right); 44 | } 45 | } 46 | result.emplace_back(move(level)); 47 | } 48 | 49 | reverse(result.begin(), result.end()); 50 | return result; 51 | } 52 | }; 53 | -------------------------------------------------------------------------------- /C++/shape-factory.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(1) 2 | // Space: O(1) 3 | 4 | /** 5 | * Your object will be instantiated and called as such: 6 | * ShapeFactory* sf = new ShapeFactory(); 7 | * Shape* shape = sf->getShape(shapeType); 8 | * shape->draw(); 9 | */ 10 | class Shape { 11 | public: 12 | virtual void draw() const=0; 13 | }; 14 | 15 | class Rectangle: public Shape { 16 | public: 17 | virtual void draw() const { 18 | cout << " ----" << endl 19 | << "| |" << endl 20 | << " ----" << endl; 21 | } 22 | }; 23 | 24 | class Square: public Shape { 25 | public: 26 | virtual void draw() const { 27 | cout << " ----" << endl 28 | << "| |" << endl 29 | << "| |" << endl 30 | << " ----" << endl; 31 | } 32 | }; 33 | 34 | class Triangle: public Shape { 35 | public: 36 | virtual void draw() const { 37 | cout << " /\\" << endl 38 | << " / \\" << endl 39 | << "/____\\" << endl; 40 | } 41 | }; 42 | 43 | class ShapeFactory { 44 | public: 45 | /** 46 | * @param shapeType a string 47 | * @return Get object of type Shape 48 | */ 49 | Shape* getShape(string& shapeType) { 50 | if (shapeType == "Square") { 51 | return new Square(); 52 | } else if (shapeType == "Triangle") { 53 | return new Triangle(); 54 | } else if (shapeType == "Rectangle") { 55 | return new Rectangle(); 56 | } 57 | } 58 | }; 59 | -------------------------------------------------------------------------------- /C++/convert-binary-search-tree-to-doubly-linked-list.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(h) 3 | 4 | /** 5 | * Definition of TreeNode: 6 | * class TreeNode { 7 | * public: 8 | * int val; 9 | * TreeNode *left, *right; 10 | * TreeNode(int val) { 11 | * this->val = val; 12 | * this->left = this->right = NULL; 13 | * } 14 | * } 15 | * Definition of Doubly-ListNode 16 | * class DoublyListNode { 17 | * public: 18 | * int val; 19 | * DoublyListNode *next, *prev; 20 | * DoublyListNode(int val) { 21 | * this->val = val; 22 | this->prev = this->next = NULL; 23 | * } 24 | * } 25 | */ 26 | class Solution { 27 | public: 28 | /** 29 | * @param root: The root of tree 30 | * @return: the head of doubly list node 31 | */ 32 | DoublyListNode* bstToDoublyList(TreeNode* root) { 33 | DoublyListNode *prev = nullptr, *head = nullptr; 34 | treeToDoublyList(root, &prev, &head); 35 | return head; 36 | } 37 | 38 | void treeToDoublyList(TreeNode *p, DoublyListNode **prev, DoublyListNode **head) { 39 | if (!p) { 40 | return; 41 | } 42 | treeToDoublyList(p->left, prev, head); 43 | DoublyListNode *root = new DoublyListNode(p->val); 44 | if (!*prev) { 45 | *head = root; 46 | } else { 47 | root->prev = *prev; 48 | (*prev)->next = root; 49 | } 50 | *prev = root; 51 | treeToDoublyList(p->right, prev, head); 52 | } 53 | }; 54 | -------------------------------------------------------------------------------- /C++/copy-list-with-random-pointer.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | /** 5 | * Definition for singly-linked list with a random pointer. 6 | * struct RandomListNode { 7 | * int label; 8 | * RandomListNode *next, *random; 9 | * RandomListNode(int x) : label(x), next(NULL), random(NULL) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | /** 15 | * @param head: The head of linked list with a random pointer. 16 | * @return: A new head of a deep copy of the list. 17 | */ 18 | RandomListNode *copyRandomList(RandomListNode *head) { 19 | // Insert the copied node after the original one. 20 | for (auto curr = head; curr; curr = curr->next->next) { 21 | auto node = new RandomListNode(curr->label); 22 | node->next = curr->next; 23 | curr->next = node; 24 | } 25 | 26 | // Update random node. 27 | for (auto curr = head; curr; curr = curr->next->next) { 28 | if (curr->random) { 29 | curr->next->random = curr->random->next; 30 | } 31 | } 32 | 33 | // Seperate the copied nodes from original ones. 34 | RandomListNode dummy{0}; 35 | for (auto curr = head, copy_curr = &dummy; 36 | curr; 37 | copy_curr = copy_curr->next, curr = curr->next) { 38 | copy_curr->next = curr->next; 39 | curr->next = curr->next->next; 40 | } 41 | 42 | return dummy.next; 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /C++/first-missing-positive.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | #include 5 | #include 6 | 7 | using std::swap; 8 | using std::vector; 9 | 10 | class Solution { 11 | public: 12 | /** 13 | * @param A: a vector of integers 14 | * @return: an integer 15 | */ 16 | int firstMissingPositive(vector A) { 17 | // Record which values are present by writing A[i] to index A[i] - 1 if A[i] 18 | // is between 1 and A.size(), inclusive. We save the value at index 19 | // A[i] - 1 by swapping it with the entry at i. If A[i] is negative or 20 | // greater than n, we just advance i. 21 | size_t i = 0; 22 | while (i < A.size()) { 23 | if (A[i] > 0 && A[i] <= A.size() && 24 | A[A[i] - 1] != A[i]) { 25 | swap(A[i], A[A[i] - 1]); 26 | } else { 27 | ++i; 28 | } 29 | } 30 | 31 | // Second pass through A to search for the first index i such that 32 | // A[i] != i+1, indicating that i + 1 is absent. If all numbers between 1 33 | // and A.size() are present, the smallest missing positive is A.size() + 1. 34 | for (size_t i = 0; i < A.size(); ++i) { 35 | if (A[i] != i + 1) { 36 | return i + 1; 37 | } 38 | } 39 | return A.size() + 1; 40 | } 41 | }; 42 | 43 | -------------------------------------------------------------------------------- /C++/max-points-on-a-line.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n^2) 2 | // Space: O(n) 3 | 4 | /** 5 | * Definition for a point. 6 | * struct Point { 7 | * int x; 8 | * int y; 9 | * Point() : x(0), y(0) {} 10 | * Point(int a, int b) : x(a), y(b) {} 11 | * }; 12 | */ 13 | class Solution { 14 | public: 15 | /** 16 | * @param points an array of point 17 | * @return an integer 18 | */ 19 | int maxPoints(vector& points) { 20 | int max_points = 0; 21 | for (int i = 0; i < points.size(); ++i) { 22 | unordered_map slope_count; 23 | const auto& start = points[i]; 24 | int same = 1; 25 | 26 | for (int j = i + 1; j < points.size(); ++j) { 27 | const auto& end = points[j]; 28 | if (start.x == end.x && start.y == end.y) { 29 | ++same; 30 | } else { 31 | auto slope = numeric_limits::max(); 32 | if (start.x - end.x != 0) { 33 | slope = (start.y - end.y) * 1.0 / (start.x - end.x); 34 | } 35 | ++slope_count[slope]; 36 | } 37 | } 38 | 39 | int current_max = same; 40 | for (const auto& kvp : slope_count) { 41 | current_max = max(current_max, kvp.second + same); 42 | } 43 | max_points = max(max_points, current_max); 44 | } 45 | 46 | return max_points; 47 | } 48 | }; 49 | -------------------------------------------------------------------------------- /C++/graph-valid-tree.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(|V| + |E|) 2 | // Space: O(|V| + |E|) 3 | 4 | class Solution { 5 | public: 6 | struct node { 7 | int parent = -1; 8 | vectorneighbors; 9 | }; 10 | 11 | bool validTree(int n, vector>& edges) { 12 | if (edges.size() != n - 1) { 13 | return false; 14 | } else if (n == 1) { 15 | return true; 16 | } 17 | 18 | unordered_map nodes; 19 | for (const auto& edge : edges) { 20 | nodes[edge.front()].neighbors.emplace_back(edge.back()); 21 | nodes[edge.back()].neighbors.emplace_back(edge.front()); 22 | } 23 | 24 | if (nodes.size() != n) { 25 | return false; 26 | } 27 | 28 | unordered_set visited; 29 | queue q; 30 | q.emplace(0); 31 | while (!q.empty()) { 32 | const int i = q.front(); 33 | q.pop(); 34 | visited.emplace(i); 35 | for (const auto& node : nodes[i].neighbors) { 36 | if (node != nodes[i].parent) { 37 | if (visited.find(node) != visited.end()) { 38 | return false; 39 | } else { 40 | visited.emplace(node); 41 | nodes[node].parent = i; 42 | q.emplace(node); 43 | } 44 | } 45 | } 46 | } 47 | return visited.size() == n; 48 | } 49 | }; 50 | -------------------------------------------------------------------------------- /C++/palindrome-linked-list.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | /** 5 | * Definition for singly-linked list. 6 | * struct ListNode { 7 | * int val; 8 | * ListNode *next; 9 | * ListNode(int x) : val(x), next(NULL) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | /** 15 | * @param head a ListNode 16 | * @return a boolean 17 | */ 18 | bool isPalindrome(ListNode* head) { 19 | // Reverse the first half list. 20 | ListNode *reverse = nullptr, *fast = head; 21 | while (fast && fast->next) { 22 | fast = fast->next->next; 23 | const auto head_next = head->next; 24 | head->next = reverse; 25 | reverse = head; 26 | head = head_next; 27 | } 28 | 29 | // If the number of the nodes is odd, 30 | // set the head of the tail list to the next of the median node. 31 | ListNode *tail = fast ? head->next : head; 32 | 33 | // Compare the reversed first half list with the second half list. 34 | // And restore the reversed first half list. 35 | bool is_palindrome = true; 36 | while (reverse) { 37 | is_palindrome = is_palindrome && reverse->val == tail->val; 38 | const auto reverse_next = reverse->next; 39 | reverse->next = head; 40 | head = reverse; 41 | reverse = reverse_next; 42 | tail = tail->next; 43 | } 44 | 45 | return is_palindrome; 46 | } 47 | }; 48 | -------------------------------------------------------------------------------- /C++/backpack-ii.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(m * n) 2 | // Space: O(m) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param m: An integer m denotes the size of a backpack 8 | * @param A & V: Given n items with size A[i] and value V[i] 9 | * @return: The maximum value 10 | */ 11 | int backPackII(int m, vector A, vector V) { 12 | // table[i][j] denotes max_value of using the first i elements 13 | // to fulfill size j. 14 | vector> table(2, vector(m + 1, INT_MIN)); 15 | int max_value = 0; 16 | table[0][0] = 0; 17 | 18 | for (int i = 1; i <= A.size(); ++i) { 19 | table[i % 2][0] = 0; 20 | for (int j = 1; j <= m; ++j) { 21 | // If first i - 1 elements could fulfill the backpack, then 22 | // first i elements would also do. 23 | table[i % 2][j] = table[(i - 1) % 2][j]; 24 | 25 | // Using the ith element to fulfill the backpack. 26 | if (j >= A[i - 1] && table[(i - 1) % 2][j - A[i - 1]] >= 0) { 27 | table[i % 2][j] = max(table[i % 2][j], 28 | table[(i - 1) % 2][j - A[i - 1]] + V[i - 1]); 29 | } 30 | 31 | // If it fulfulls size j, update max size. 32 | if (table[i % 2][j] >= 0) { 33 | max_value = max(max_value, table[i % 2][j]); 34 | } 35 | } 36 | } 37 | return max_value; 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /C++/minimum-adjustment-cost.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(k * n * t), n is size of array, k is the largest number in array, t is target 2 | // Space: O(k) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param A: An integer array. 8 | * @param target: An integer. 9 | */ 10 | int MinAdjustmentCost(vector A, int target) { 11 | const int n = A.size(); 12 | const int max_num = 100; 13 | 14 | // min_cost[i][j] denotes the min cost of the first i elements 15 | // with target j. 16 | vector> min_cost(2, vector(max_num + 1, 0)); 17 | 18 | for (int i = 1; i <= n; ++i) { 19 | for (int j = 1; j <= max_num; ++j) { 20 | // min_cost[i][j] = abs(A[i - 1] - j) + 21 | // min(min_cost[i][k], 22 | // for each k s.t. | k - j | <= target) 23 | int upper = min(max_num, j + target); 24 | int lower = max(1, j - target); 25 | min_cost[i % 2][j] = INT_MAX; 26 | for (int k = lower; k <= upper; ++k) { 27 | min_cost[i % 2][j] = min(min_cost[i % 2][j], 28 | min_cost[(i - 1) % 2][k]); 29 | } 30 | min_cost[i % 2][j] += abs(A[i - 1] - j); 31 | } 32 | } 33 | 34 | // return min of min_cost[n] excluding min_cost[n][0] 35 | return *min_element(next(min_cost[n % 2].cbegin()), min_cost[n % 2].cend()); 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /C++/number-of-islands.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(m * n) 2 | // Space: O(m * n) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param grid a boolean 2D matrix 8 | * @return an integer 9 | */ 10 | int numIslands(vector>& grid) { 11 | if (grid.empty()) { 12 | return 0; 13 | } 14 | 15 | vector> used(grid.size(), 16 | vector(grid[0].size(), false)); 17 | 18 | int count = 0; 19 | for (int i = 0; i < grid.size(); ++i) { 20 | for (int j = 0; j < grid[0].size(); ++j) { 21 | if (grid[i][j] && !used[i][j]) { 22 | findIsland(grid, i, j, &used); 23 | ++count; 24 | } 25 | } 26 | } 27 | return count; 28 | } 29 | 30 | void findIsland(const vector>& grid, 31 | const int x, 32 | const int y, 33 | vector> *used) { 34 | if (!grid[x][y] || (*used)[x][y]) { 35 | return; 36 | } 37 | 38 | (*used)[x][y] = true; 39 | if (x > 0) { 40 | findIsland(grid, x - 1, y, used); 41 | } 42 | if (x < grid.size() - 1) { 43 | findIsland(grid, x + 1, y, used); 44 | } 45 | if (y > 0) { 46 | findIsland(grid, x, y - 1, used); 47 | } 48 | if (y < grid[0].size() - 1) { 49 | findIsland(grid, x, y + 1, used); 50 | } 51 | } 52 | }; 53 | -------------------------------------------------------------------------------- /C++/flatten-list.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(h) 3 | 4 | /** 5 | * // This is the interface that allows for creating nested lists. 6 | * // You should not implement it, or speculate about its implementation 7 | * class NestedInteger { 8 | * public: 9 | * // Return true if this NestedInteger holds a single integer, 10 | * // rather than a nested list. 11 | * bool isInteger() const; 12 | * 13 | * // Return the single integer that this NestedInteger holds, 14 | * // if it holds a single integer 15 | * // The result is undefined if this NestedInteger holds a nested list 16 | * int getInteger() const; 17 | * 18 | * // Return the nested list that this NestedInteger holds, 19 | * // if it holds a nested list 20 | * // The result is undefined if this NestedInteger holds a single integer 21 | * const vector &getList() const; 22 | * }; 23 | */ 24 | class Solution { 25 | public: 26 | // @param nestedList a list of NestedInteger 27 | // @return a list of integer 28 | vector flatten(vector &nestedList) { 29 | vector result; 30 | for (const auto& node : nestedList) 31 | if (node.isInteger()) { 32 | result.emplace_back(node.getInteger()); 33 | } else { 34 | vector sub_list = node.getList(); 35 | auto temp = flatten(sub_list); 36 | result.insert(result.end(), temp.begin(), temp.end()); 37 | } 38 | 39 | return result; 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /C++/3-sum-closest.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n^2) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param numbers: Give an array numbers of n integer 8 | * @param target: An integer 9 | * @return: return the sum of the three integers, the sum closest target. 10 | */ 11 | int threeSumClosest(vector nums, int target) { 12 | int ans = numeric_limits::max(); 13 | int min_diff = numeric_limits::max(); 14 | 15 | // Make nums in increasing order. Time: O(nlogn) 16 | sort(nums.begin(), nums.end()); 17 | 18 | for (int i = 0; i < static_cast(nums.size()) - 2; ++i) { 19 | if (i == 0 || nums[i] != nums[i - 1]) { // Skip duplicated. 20 | int j = i + 1; 21 | int k = nums.size() - 1; 22 | 23 | while (j < k) { // Time: O(n) for each i. 24 | const auto sum = nums[i] + nums[j] + nums[k]; 25 | 26 | if (sum > target) { // Should decrease sum. 27 | --k; 28 | } else if (sum < target) { // Should increase sum. 29 | ++j; 30 | } else { 31 | return target; 32 | } 33 | 34 | if (abs(sum - target) < min_diff) { 35 | min_diff = abs(sum - target); 36 | ans = sum; 37 | } 38 | } 39 | } 40 | } 41 | 42 | return ans; 43 | } 44 | }; 45 | 46 | 47 | -------------------------------------------------------------------------------- /C++/copy-books.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(nlogp), p is total pages. 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param pages: a vector of integers 8 | * @param k: an integer 9 | * @return: an integer 10 | */ 11 | int copyBooks(vector &pages, int k) { 12 | if (k >= pages.size()) { 13 | return *max_element(pages.cbegin(), pages.cend()); 14 | } 15 | 16 | int sum = 0; 17 | for (const auto& page : pages) { 18 | sum += page; 19 | } 20 | int average = sum / k; // Lower bound. 21 | return binarySearch(pages, k, average, sum); 22 | } 23 | 24 | int binarySearch(const vector &pages, 25 | const int k, int left, int right) { 26 | while (left <= right) { 27 | const auto mid = left + (right - left) / 2; 28 | if (valid(pages, k, mid)) { 29 | right = mid - 1; 30 | } else { 31 | left = mid + 1; 32 | } 33 | } 34 | return left; 35 | } 36 | 37 | // Check whether everyone copying at most x pages works or not. 38 | bool valid(const vector &pages, const int k, const int x) { 39 | int sum = 0; 40 | int people = 0; 41 | for (int i = 0; i < pages.size() && people < k; ++i) { 42 | if (sum + pages[i] > x) { 43 | sum = 0; 44 | ++people; 45 | } 46 | sum += pages[i]; 47 | } 48 | return people < k && sum <= x; 49 | } 50 | }; 51 | -------------------------------------------------------------------------------- /C++/interleaving-positive-and-negative-numbers.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param A: An integer array. 8 | * @return: void 9 | */ 10 | void rerange(vector &A) { 11 | int n = A.size(); 12 | 13 | // by default, start with negative in output array 14 | int expectPostive = false; 15 | int postiveCount = 0; 16 | for (const auto& k : A) { 17 | postiveCount += k > 0? 1 : 0; 18 | } 19 | 20 | // if there are more postive than negative, start with postive 21 | if (2 * postiveCount > n) { 22 | expectPostive = true; 23 | } 24 | 25 | int pos = 0, neg = 0; 26 | int i = 0; 27 | 28 | while (pos < n && neg < n) { 29 | // A[pos] is the next negative 30 | while (pos < n && A[pos] > 0) { 31 | ++pos; 32 | } 33 | // A[pos] is the next postive 34 | while (neg < n && A[neg] < 0) { 35 | ++neg; 36 | } 37 | 38 | if (expectPostive && A[i] < 0) { 39 | swap(A[i], A[neg]); 40 | } 41 | 42 | if (!expectPostive && A[i] > 0) { 43 | swap(A[i], A[pos]); 44 | } 45 | 46 | if (i == pos) { 47 | ++pos; 48 | } 49 | if (i == neg) { 50 | ++neg; 51 | } 52 | 53 | expectPostive = !expectPostive; 54 | ++i; 55 | } 56 | } 57 | }; 58 | -------------------------------------------------------------------------------- /C++/sort-integers.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) ~ O(n^2) 2 | // Space: O(1) 3 | 4 | // In-place insertion sort. (stable) 5 | class Solution { 6 | public: 7 | /** 8 | * @param A an integer array 9 | * @return void 10 | */ 11 | void sortIntegers(vector& A) { 12 | for (int n = 0; n < A.size(); ++n) { 13 | for (int i = n - 1; i >= 0 && A[i] > A[i + 1]; --i) { 14 | swap(A[i], A[i + 1]); 15 | } 16 | } 17 | } 18 | }; 19 | 20 | // Time: O(n^2) 21 | // Space: O(1) 22 | // Bubble sort. (stable) 23 | class Solution { 24 | public: 25 | /** 26 | * @param A an integer array 27 | * @return void 28 | */ 29 | void sortIntegers(vector& A) { 30 | for (int n = 0; n < A.size(); ++n) { 31 | for (int i = 0; i + 1 < static_cast(A.size()) - n; ++i) { 32 | if (A[i] > A[i + 1]) { 33 | swap(A[i], A[i + 1]); 34 | } 35 | } 36 | } 37 | } 38 | }; 39 | 40 | // Time: O(n^2) 41 | // Space: O(1) 42 | // Selection sort. (unstable) 43 | class Solution { 44 | public: 45 | /** 46 | * @param A an integer array 47 | * @return void 48 | */ 49 | void sortIntegers(vector& A) { 50 | for (int n = 0; n < A.size(); ++n) { 51 | int min_idx = n; 52 | for (int i = n + 1; i < A.size(); ++i) { 53 | if (A[i] < A[min_idx]) { 54 | min_idx = i; 55 | } 56 | } 57 | swap(A[n], A[min_idx]); 58 | } 59 | } 60 | }; 61 | -------------------------------------------------------------------------------- /Python/maximum-gap.py: -------------------------------------------------------------------------------- 1 | # Time: O(n) 2 | # Space: O(n) 3 | class Solution: 4 | # @param numss: a list of integers 5 | # @return: the maximum difference 6 | def maximumGap(self, nums): 7 | if len(nums) < 2: 8 | return 0 9 | 10 | # Init bucket. 11 | max_val, min_val = max(nums), min(nums) 12 | gap = max(1, (max_val - min_val) / (len(nums) - 1)) 13 | bucket_size = (max_val - min_val) / gap + 1 14 | bucket = [{'min':float("inf"), 'max':float("-inf")} \ 15 | for _ in xrange(bucket_size)] 16 | 17 | # Find the bucket where the n should be put. 18 | for n in nums: 19 | # min_val / max_val is in the first / last bucket. 20 | if n in (max_val, min_val): 21 | continue 22 | i = (n - min_val) / gap 23 | bucket[i]['min'] = min(bucket[i]['min'], n) 24 | bucket[i]['max'] = max(bucket[i]['max'], n) 25 | 26 | # Count each bucket gap between the first and the last bucket. 27 | max_gap, pre_bucket_max = 0, min_val 28 | for i in xrange(bucket_size): 29 | # Skip the bucket it empty. 30 | if bucket[i]['min'] == float("inf") and \ 31 | bucket[i]['max'] == float("-inf"): 32 | continue 33 | max_gap = max(max_gap, bucket[i]['min'] - pre_bucket_max) 34 | pre_bucket_max = bucket[i]['max'] 35 | # Count the last bucket. 36 | max_gap = max(max_gap, max_val - pre_bucket_max) 37 | 38 | return max_gap 39 | -------------------------------------------------------------------------------- /C++/subarray-sum-closest.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(nlogn) 2 | // Space: O(n) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param nums: A list of integers 8 | * @return: A list of integers includes the index of the first number 9 | * and the index of the last number 10 | */ 11 | vector subarraySumClosest(vector nums) { 12 | const int n = nums.size(); 13 | 14 | if (n == 1) { 15 | return {0, 0}; 16 | } 17 | 18 | // sum_from_start[i] denotes sum for 0 ~ i - 1. 19 | vector> sum_from_start(n + 1, {0, 0}); 20 | sum_from_start[0].second = -1; // For case closest sum is from 0. 21 | for (int i = 0; i < n; ++i) { 22 | sum_from_start[i + 1].first = sum_from_start[i].first + nums[i]; 23 | sum_from_start[i + 1].second = i; 24 | } 25 | 26 | // Sort each sum from start. 27 | sort(sum_from_start.begin(), sum_from_start.end()); 28 | 29 | int min_diff = INT_MAX; 30 | int start = -1; 31 | int end = -1; 32 | 33 | // Find min difference of adjacent sum. 34 | for (int i = 1; i <= n; ++i) { 35 | int diff = abs(sum_from_start[i].first - sum_from_start[i - 1].first); 36 | if (diff < min_diff) { 37 | min_diff = diff; 38 | start = min(sum_from_start[i].second, sum_from_start[i - 1].second) + 1; 39 | end = max(sum_from_start[i].second, sum_from_start[i - 1].second); 40 | } 41 | } 42 | 43 | return {start, end}; 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /C++/the-smallest-difference.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(max(m, n) * log(min(m, n))) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param A, B: Two integer arrays. 8 | * @return: Their smallest difference. 9 | */ 10 | int smallestDifference(vector &A, vector &B) { 11 | if (A.size() > B.size()) { 12 | return smallestDifference(B, A); 13 | } 14 | sort(A.begin(), A.end()); 15 | 16 | int min_diff = numeric_limits::max(); 17 | for (const auto& b : B) { 18 | auto it = lower_bound(A.cbegin(), A.cend(), b); 19 | if (it != A.cend()) { 20 | min_diff = min(min_diff, *it - b); 21 | } 22 | if (it != A.cbegin()) { 23 | --it; 24 | min_diff = min(min_diff, b - *it); 25 | } 26 | } 27 | 28 | return min_diff; 29 | } 30 | }; 31 | 32 | // Time: O(nlogn) 33 | // Space: O(1) 34 | class Solution2 { 35 | public: 36 | /** 37 | * @param A, B: Two integer arrays. 38 | * @return: Their smallest difference. 39 | */ 40 | int smallestDifference(vector &A, vector &B) { 41 | sort(A.begin(), A.end()); 42 | sort(B.begin(), B.end()); 43 | 44 | int i = 0; 45 | int j = 0; 46 | int min_diff = numeric_limits::max(); 47 | 48 | while (i < A.size() && j < B.size()) { 49 | min_diff = min(min_diff, abs(A[i] - B[j])); 50 | A[i] < B[j] ? ++i : ++j; 51 | } 52 | 53 | return min_diff; 54 | } 55 | }; 56 | 57 | -------------------------------------------------------------------------------- /C++/binary-tree-paths.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n * h) 2 | // Space: O(h) 3 | 4 | /** 5 | * Definition of TreeNode: 6 | * class TreeNode { 7 | * public: 8 | * int val; 9 | * TreeNode *left, *right; 10 | * TreeNode(int val) { 11 | * this->val = val; 12 | * this->left = this->right = NULL; 13 | * } 14 | * } 15 | */ 16 | class Solution { 17 | public: 18 | /** 19 | * @param root the root of the binary tree 20 | * @return all root-to-leaf paths 21 | */ 22 | vector binaryTreePaths(TreeNode* root) { 23 | vector result; 24 | vector path; 25 | binaryTreePathsRecu(root, &path, &result); 26 | return result; 27 | } 28 | 29 | void binaryTreePathsRecu(TreeNode *node, vector *path, 30 | vector *result) { 31 | if (!node) { 32 | return; 33 | } 34 | 35 | if (!node->left && !node->right) { 36 | string ans = ""; 37 | for (const auto& n : *path) { 38 | ans.append(to_string(n->val).append("->")); 39 | } 40 | result->emplace_back(move(ans.append(to_string(node->val)))); 41 | } 42 | 43 | if (node->left) { 44 | path->emplace_back(node); 45 | binaryTreePathsRecu(node->left, path, result); 46 | path->pop_back(); 47 | } 48 | 49 | if (node->right) { 50 | path->emplace_back(node); 51 | binaryTreePathsRecu(node->right, path, result); 52 | path->pop_back(); 53 | } 54 | } 55 | }; 56 | -------------------------------------------------------------------------------- /C++/sort-list.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(nlogn) 2 | // Space: O(logn) 3 | 4 | /** 5 | * Definition of ListNode 6 | * class ListNode { 7 | * public: 8 | * int val; 9 | * ListNode *next; 10 | * ListNode(int val) { 11 | * this->val = val; 12 | * this->next = NULL; 13 | * } 14 | * } 15 | */ 16 | class Solution { 17 | public: 18 | /** 19 | * @param head: The first node of linked list. 20 | * @return: You should return the head of the sorted linked list, 21 | using constant space complexity. 22 | */ 23 | ListNode *sortList(ListNode *head) { 24 | if (!head || !head->next) { 25 | return head; 26 | } 27 | 28 | auto slow = head, fast = head; 29 | while (fast->next && fast->next->next) { 30 | slow = slow->next; 31 | fast = fast->next->next; 32 | } 33 | 34 | // Split linked list. 35 | fast = slow; 36 | slow = slow->next; 37 | fast->next = nullptr; 38 | 39 | return mergeTwoLists(sortList(head), sortList(slow)); 40 | } 41 | 42 | private: 43 | ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) { 44 | ListNode dummy{0}; 45 | auto curr = &dummy; 46 | 47 | while (l1 && l2) { 48 | if (l1->val <= l2->val) { 49 | curr->next = l1; 50 | l1 = l1->next; 51 | } else { 52 | curr->next = l2; 53 | l2 = l2->next; 54 | } 55 | curr = curr->next; 56 | } 57 | curr->next = l1 ? l1 : l2; 58 | 59 | return dummy.next; 60 | } 61 | }; 62 | -------------------------------------------------------------------------------- /C++/3-sum.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n^2) 2 | // Space: O(1) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param numbers : Give an array numbers of n integer 8 | * @return : Find all unique triplets in the array which gives the sum of zero. 9 | */ 10 | vector> threeSum(vector &nums) { 11 | vector> ans; 12 | const int target = 0; 13 | 14 | // Make nums in increasing order. Time: O(nlogn) 15 | sort(nums.begin(), nums.end()); 16 | 17 | for (int i = 0; i < static_cast(nums.size()) - 2; ++i) { 18 | if (i == 0 || nums[i] != nums[i - 1]) { // Skip duplicated. 19 | for (int j = i + 1, k = nums.size() - 1; j < k; ) { // Time: O(n) for each i. 20 | if (j - 1 > i && nums[j] == nums[j - 1]) { // Skip duplicated. 21 | ++j; 22 | } else if (k + 1 < nums.size() && nums[k] == nums[k + 1]) { // Skip duplicated. 23 | --k; 24 | } else { 25 | const auto sum = nums[i] + nums[j] + nums[k]; 26 | if (sum > target) { // Should decrease sum. 27 | --k; 28 | } else if (sum < target) { // Should increase sum. 29 | ++j; 30 | } else { 31 | ans.push_back({nums[i], nums[j], nums[k]}); 32 | ++j, --k; 33 | } 34 | } 35 | } 36 | } 37 | } 38 | 39 | return ans; 40 | } 41 | }; 42 | 43 | -------------------------------------------------------------------------------- /C++/compare-strings.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(c) 3 | 4 | // len(A) is much larger than len(B), this solution is better 5 | class Solution { 6 | public: 7 | /** 8 | * @param A: A string includes Upper Case letters 9 | * @param B: A string includes Upper Case letter 10 | * @return: if string A contains all of the characters in B return true 11 | * else return false 12 | */ 13 | bool compareStrings(string A, string B) { 14 | unordered_map h; 15 | for (const auto& c: B) { 16 | ++h[c]; 17 | } 18 | 19 | size_t cnt = B.length(); 20 | for (const auto& c: A) { 21 | if (h[c] > 0) { 22 | --h[c]; 23 | --cnt; 24 | } 25 | if (cnt == 0) { 26 | return true; 27 | } 28 | } 29 | 30 | if (cnt > 0) { 31 | return false; 32 | } 33 | 34 | return true; 35 | } 36 | }; 37 | 38 | class Solution2 { 39 | public: 40 | /** 41 | * @param A: A string includes Upper Case letters 42 | * @param B: A string includes Upper Case letter 43 | * @return: if string A contains all of the characters in B return true 44 | * else return false 45 | */ 46 | bool compareStrings(string A, string B) { 47 | unordered_map h; 48 | for (const auto& c: A) { 49 | ++h[c]; 50 | } 51 | 52 | for (const auto& c: B) { 53 | if (--h[c] < 0) { 54 | return false; 55 | } 56 | } 57 | 58 | return true; 59 | } 60 | }; 61 | 62 | -------------------------------------------------------------------------------- /C++/find-the-connected-component-in-the-undirected-graph.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(n) 3 | 4 | /** 5 | * Definition for Undirected graph. 6 | * struct UndirectedGraphNode { 7 | * int label; 8 | * vector neighbors; 9 | * UndirectedGraphNode(int x) : label(x) {}; 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | /** 15 | * @param nodes a array of Undirected graph node 16 | * @return a connected set of a Undirected graph 17 | */ 18 | vector> connectedSet(vector& nodes) { 19 | vector> components; 20 | queue q; 21 | unordered_set visited; 22 | 23 | for (const auto& node : nodes) { 24 | if (visited.find(node) == visited.end()) { 25 | visited.emplace(node); 26 | q.emplace(node); 27 | 28 | vector component; 29 | while (!q.empty()) { 30 | auto node = q.front(); 31 | q.pop(); 32 | component.emplace_back(node->label); 33 | for (const auto& n : node->neighbors) { 34 | if (visited.find(n) == visited.end()) { 35 | visited.emplace(n); 36 | q.emplace(n); 37 | } 38 | } 39 | } 40 | // Sort component. 41 | sort(component.begin(), component.end()); 42 | components.emplace_back(move(component)); 43 | } 44 | } 45 | 46 | return components; 47 | } 48 | }; 49 | -------------------------------------------------------------------------------- /C++/heapify.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n) 2 | // Space: O(1) 3 | 4 | // Bottom-Up. 5 | class Solution { 6 | public: 7 | /** 8 | * @param A: Given an integer array 9 | * @return: void 10 | */ 11 | void heapify(vector &A) { 12 | for (int i = A.size() / 2; i >= 0; --i) { 13 | sift_down(A, i); 14 | } 15 | } 16 | 17 | void sift_down(vector& A, int index) { 18 | while (index < A.size()) { 19 | int smallest = index; 20 | if (index * 2 + 1 < A.size() && A[index * 2 + 1] < A[smallest]) { 21 | smallest = index * 2 + 1; 22 | } 23 | if (index * 2 + 2 < A.size() && A[index * 2 + 2] < A[smallest]) { 24 | smallest = index * 2 + 2; 25 | } 26 | if (smallest == index) { 27 | break; 28 | } 29 | swap(A[smallest], A[index]); 30 | index = smallest; 31 | } 32 | } 33 | }; 34 | 35 | 36 | // Time: O(nlogn) 37 | // Space: O(1) 38 | // Top-Down. 39 | class Solution2 { 40 | public: 41 | /** 42 | * @param A: Given an integer array 43 | * @return: void 44 | */ 45 | void heapify(vector &A) { 46 | for (int i = 0; i < A.size(); ++i) { 47 | sift_up(A, i); 48 | } 49 | } 50 | 51 | void sift_up(vector& A, int index) { 52 | while ((index - 1) / 2 >= 0) { 53 | int parent = (index - 1) / 2; 54 | if (A[index] < A[parent]) { 55 | swap(A[parent], A[index]); 56 | index = parent; 57 | } else { 58 | break; 59 | } 60 | } 61 | } 62 | }; 63 | 64 | -------------------------------------------------------------------------------- /C++/restore-ip-addresses.cpp: -------------------------------------------------------------------------------- 1 | // Time: O(n^m) = O(3^4) 2 | // Space: O(n * m) = O(3 * 4) 3 | 4 | class Solution { 5 | public: 6 | /** 7 | * @param s the IP string 8 | * @return All possible valid IP addresses 9 | */ 10 | vector restoreIpAddresses(string& s) { 11 | vector result; 12 | string cur; 13 | restoreIpAddressesHelper(s, 0, 0, &cur, &result); 14 | return result; 15 | } 16 | 17 | void restoreIpAddressesHelper(const string& s, 18 | int start, int dots, 19 | string *cur, 20 | vector *result) { 21 | // Pruning to improve performance. 22 | if (((4 - dots) * 3 < s.length() - start) || 23 | ((4 - dots) > s.length() - start)) { 24 | return; 25 | } 26 | 27 | if (start == s.length() && dots == 4) { 28 | result->emplace_back(cur->begin(), prev(cur->end())); 29 | } else { 30 | for (int i = start; i < start + 3; ++i) { 31 | string tmp = s.substr(start, i - start + 1); 32 | if (i < s.length() && isValid(tmp)) { 33 | tmp.push_back('.'); 34 | cur->append(tmp); 35 | restoreIpAddressesHelper(s, i + 1, dots + 1, cur, result); 36 | cur->resize(cur->length() - (i - start + 2)); 37 | } 38 | } 39 | } 40 | } 41 | 42 | bool isValid(const string &s) { 43 | if (s.empty() || (s[0] == '0' && s != "0")) { 44 | return false; 45 | } 46 | return stoi(s) < 256; 47 | } 48 | }; 49 | --------------------------------------------------------------------------------