├── .gitignore ├── CC150 ├── README.md ├── build ├── chap1 │ ├── compress.cpp │ ├── replaceSpace.cpp │ ├── reverse.cpp │ └── rotate.cpp ├── chap11 │ └── mergeArray.cpp ├── chap2 │ ├── getLoopFront.cpp │ └── removeDuplicate.cpp ├── chap3 │ ├── minStack.cpp │ ├── sortStack.cpp │ └── sortStack2.cpp ├── chap5 │ └── toBinary.cpp └── chap7 │ └── getKthNum.cpp ├── EPI ├── 1501-sort-stock-trade.cpp └── build ├── Geeks4Geeks ├── README.md ├── build └── quicksort-on-singly-linked-list.cpp ├── LeetCode ├── 3sum-closest.cpp ├── 3sum.cpp ├── 4sum.cpp ├── README.md ├── add-binary.cpp ├── add-two-numbers.cpp ├── anagrams.cpp ├── balanced-binary-tree.cpp ├── best-time-to-buy-and-sell-stock-ii.cpp ├── best-time-to-buy-and-sell-stock-iii.cpp ├── best-time-to-buy-and-sell-stock.cpp ├── binary-tree-inorder-traversal.cpp ├── binary-tree-level-order-traversal-ii.cpp ├── binary-tree-level-order-traversal.cpp ├── binary-tree-maximum-path-sum.cpp ├── binary-tree-postorder-traversal.cpp ├── binary-tree-preorder-traversal.cpp ├── binary-tree-zigzag-level-order-traversal.cpp ├── candy.cpp ├── climbing-stairs.cpp ├── clone-graph.cpp ├── combination-sum-ii.cpp ├── combination-sum.cpp ├── combinations.cpp ├── construct-binary-tree-from-inorder-and-postorder-traversal.cpp ├── construct-binary-tree-from-preorder-and-inorder-traversal.cpp ├── container-with-most-water.cpp ├── convert-sorted-array-to-binary-search-tree.cpp ├── convert-sorted-list-to-binary-search-tree.cpp ├── copy-list-with-random-pointer.cpp ├── count-and-say.cpp ├── decode-ways.cpp ├── distinct-subsequences.cpp ├── divide-two-integers.cpp ├── edit-distance.cpp ├── evaluate-reverse-polish-notation.cpp ├── first-missing-positive.cpp ├── flatten-binary-tree-to-linked-list.cpp ├── gas-station.cpp ├── generate-parentheses.cpp ├── gray-code.cpp ├── implement-strstr.cpp ├── insert-interval.cpp ├── insertion-sort-list.cpp ├── integer-to-roman.cpp ├── jump-game-ii.cpp ├── jump-game.cpp ├── largest-rectangle-in-histogram.cpp ├── length-of-last-word.cpp ├── letter-combinations-of-a-phone-number.cpp ├── linked-list-cycle-ii.cpp ├── linked-list-cycle.cpp ├── longest-common-prefix.cpp ├── longest-consecutive-sequence.cpp ├── longest-palindromic-substring-manacher.cpp ├── longest-palindromic-substring.cpp ├── longest-substring-without-repeating-characters.cpp ├── longest-valid-parentheses.cpp ├── lru-cache.cpp ├── max-points-on-a-line.cpp ├── maximal-rectangle.cpp ├── maximum-depth-of-binary-tree.cpp ├── maximum-subarray.cpp ├── median-of-two-sorted-arrays.cpp ├── merge-intervals.cpp ├── merge-k-sorted-lists.cpp ├── merge-sorted-array.cpp ├── merge-two-sorted-lists.cpp ├── minimum-depth-of-binary-tree-bfs.cpp ├── minimum-depth-of-binary-tree-dfs.cpp ├── minimum-path-sum.cpp ├── minimum-window-substring.cpp ├── multiply-strings.cpp ├── n-queens-ii.cpp ├── n-queens.cpp ├── next-permutation.cpp ├── palindrome-number.cpp ├── palindrome-partitioning-ii.cpp ├── palindrome-partitioning.cpp ├── partition-list.cpp ├── pascals-triangle-ii.cpp ├── pascals-triangle.cpp ├── path-sum-ii.cpp ├── path-sum.cpp ├── permutation-sequence.cpp ├── permutations-ii.cpp ├── permutations.cpp ├── plus-one.cpp ├── populating-next-right-pointers-in-each-node-ii.cpp ├── populating-next-right-pointers-in-each-node.cpp ├── powx-n.cpp ├── recover-binary-search-tree.cpp ├── regular-expression-matching.cpp ├── remove-duplicates-from-sorted-array-ii.cpp ├── remove-duplicates-from-sorted-array.cpp ├── remove-duplicates-from-sorted-list-ii.cpp ├── remove-duplicates-from-sorted-list.cpp ├── remove-element.cpp ├── remove-nth-node-from-end-of-list.cpp ├── reorder-list.cpp ├── restore-ip-addresses.cpp ├── reverse-integer.cpp ├── reverse-linked-list-ii.cpp ├── reverse-nodes-in-k-group.cpp ├── reverse-words-in-a-string.cpp ├── roman-to-integer.cpp ├── rotate-image.cpp ├── rotate-list.cpp ├── same-tree.cpp ├── scramble-string.cpp ├── search-a-2d-matrix.cpp ├── search-for-a-range.cpp ├── search-in-rotated-sorted-array-ii.cpp ├── search-in-rotated-sorted-array.cpp ├── search-insert-position.cpp ├── set-matrix-zeroes.cpp ├── simplify-path.cpp ├── single-number-ii.cpp ├── single-number.cpp ├── sort-color.cpp ├── sort-list.cpp ├── spiral-matrix-ii.cpp ├── spiral-matrix.cpp ├── sqrtx.cpp ├── string-to-integer-atoi.cpp ├── subsets-ii.cpp ├── subsets.cpp ├── substring-with-concatenation-of-all-words.cpp ├── sudoku-solver.cpp ├── sum-root-to-leaf-numbers.cpp ├── surrounded-regions.cpp ├── swap-nodes-in-pairs.cpp ├── symmetric-tree.cpp ├── text-justification.cpp ├── trapping-rain-water.cpp ├── triangle.cpp ├── two-sum.cpp ├── unique-binary-search-trees-ii.cpp ├── unique-binary-search-trees.cpp ├── unique-paths-ii.cpp ├── unique-paths.cpp ├── valid-number.cpp ├── valid-palindrome.cpp ├── valid-parentheses.cpp ├── valid-sudoku.cpp ├── validate-binary-search-tree-bottom-up.cpp ├── validate-binary-search-tree.cpp ├── wildcard-matching.cpp ├── word-break-ii.cpp ├── word-break.cpp ├── word-ladder-ii.cpp ├── word-ladder.cpp ├── word-search.cpp └── zigzag-conversion.cpp ├── MockInterview ├── build ├── compute-process-time.cpp ├── delete-node.cpp ├── first-duplicate-num.cpp └── json-parser.cpp └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Compiled Dynamic libraries 8 | *.so 9 | *.dylib 10 | *.dll 11 | 12 | # Compiled Static libraries 13 | *.lai 14 | *.la 15 | *.a 16 | *.lib 17 | 18 | # Executables 19 | *.exe 20 | *.out 21 | *.app 22 | -------------------------------------------------------------------------------- /CC150/README.md: -------------------------------------------------------------------------------- 1 | # Cracking the Coding Interview | Solutions 2 | * Chapter 1: Arrays and Strings 3 | * Chapter 2: Linked Lists 4 | * Chapter 3: Stacks and Queues 5 | * Chapter 4: Trees and Graphs 6 | * Chapter 5: Bit Manipulation 7 | * Chapter 6: Brain Teasers [Read] 8 | * Chapter 7: Mathematics and Probability 9 | * Chapter 8: Object-Oriented Design [Read] 10 | * Chapter 9: Recursion and Dynamic Programming 11 | * Chapter 10: Scalability and Memory Limits [Read] 12 | * Chapter 11: Sorting and Searching 13 | * Chapter 12: Testing [Read] 14 | -------------------------------------------------------------------------------- /CC150/build: -------------------------------------------------------------------------------- 1 | if [ -z "$1" ] 2 | then 3 | echo "No argu supplied" 4 | exit 1 5 | fi 6 | name=$1 7 | echo compile and run $name 8 | g++ -c $name.cpp -std=c++11 9 | g++ $name.o -o $name.out 10 | ./$name.out 11 | rm $name.out 12 | rm $name.o 13 | -------------------------------------------------------------------------------- /CC150/chap1/compress.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | string compress(string str) { 7 | int len = str.size(); 8 | if(len <= 1) return str; 9 | ostringstream oss; 10 | char cur = str[0]; 11 | int cnt = 1; 12 | for(int i=1; i str.size()) return str; 24 | else return res; 25 | } 26 | 27 | int main() { 28 | cout << compress("aabcccccaaa") << endl; 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /CC150/chap1/replaceSpace.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | void replaceString(char *str, int len) { 6 | // first scan 7 | int space_count = 0; 8 | char *p = str; 9 | while(*p) { 10 | if(*p == ' ') space_count ++; 11 | p++; 12 | } 13 | if(space_count == 0) return; 14 | int extend_len = len + space_count * 2; 15 | 16 | // second scan 17 | int ei = extend_len - 1; 18 | int i = len - 1; 19 | str[extend_len] = 0; 20 | while(ei >= 0) { 21 | if(str[i] == ' ') { 22 | str[ei] = '0'; 23 | str[ei-1] = '2'; 24 | str[ei-2] = '%'; 25 | ei -= 3; 26 | } else { 27 | str[ei] = str[i]; 28 | ei -= 1; 29 | } 30 | i -= 1; 31 | if(ei == i) break; 32 | } 33 | } 34 | 35 | int main() { 36 | char *p = new char[100]; 37 | strcpy(p, "hello world"); 38 | replaceString(p, strlen(p)); 39 | cout << p << endl; 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /CC150/chap1/reverse.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | void reverse(char *str) { 6 | char *start=str, *end=str; 7 | while(*end) ++end; 8 | end --; 9 | while(start < end) { 10 | swap(*start, *end); 11 | start++; 12 | end--; 13 | } 14 | 15 | } 16 | 17 | int main() { 18 | char *str = new char[20]; 19 | strcpy(str, "hello world"); 20 | reverse(str); 21 | cout << str << endl; 22 | } 23 | -------------------------------------------------------------------------------- /CC150/chap1/rotate.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | void rotate(vector > &matrix) { 6 | // do a turn according to the diagonal 7 | if(matrix.empty()) return; 8 | int row = matrix.size(); 9 | int col = matrix[0].size(); 10 | for(int i=0; i > matrix(2, vector(2, 1) ); 25 | matrix[0][1] = 2; matrix[1][0] = 3; matrix[1][1] = 4; 26 | rotate(matrix); 27 | for(auto &v:matrix) { 28 | for(auto x: v) { 29 | cout << x << " "; 30 | } 31 | cout << endl; 32 | } 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /CC150/chap11/mergeArray.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | void merge(int A[], int B[], int lenA, int lenB) { 5 | int i=lenA-1, j=lenB-1; 6 | int k=lenA+lenB-1; 7 | while(i >=0 && j >=0) { 8 | if(A[i] > B[j]) { 9 | A[k--] = A[i--]; 10 | } else { 11 | A[k--] = B[j--]; 12 | } 13 | } 14 | while(j>=0) A[k--] = B[j--]; 15 | } 16 | 17 | int main() { 18 | int A[30], B[10]; 19 | for(int i=0; i<10; i++) { 20 | A[i] = i*i*2 - 2*i + 8; 21 | B[i] = 8*i + 4; 22 | } 23 | merge(A, B, 10, 10); 24 | for(int i=0; i<20; i++) { 25 | cout << A[i] << " "; 26 | } 27 | cout << endl; 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /CC150/chap2/getLoopFront.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | struct ListNode { 5 | int val; 6 | ListNode *next; 7 | ListNode(int x) { val = x; next = nullptr; } 8 | }; 9 | 10 | ListNode *getLoopFront(ListNode *head) { 11 | if(head == nullptr || head->next == nullptr) return head; 12 | ListNode *slow = head, *fast = head; 13 | // run until they meet in LoopSize-k%LoopSize 14 | while(slow != nullptr && fast != nullptr) { 15 | slow = slow->next; 16 | fast = fast->next->next; 17 | if(slow == fast) break; 18 | } 19 | 20 | // run another k steps to get to the collide point 21 | slow = head; 22 | while(slow != fast) { 23 | slow = slow->next; 24 | fast = fast->next; 25 | } 26 | return fast; 27 | } 28 | 29 | int main() { 30 | ListNode a(1), b(2), c(3), d(4), e(5), f(6), g(7), h(8), i(9), j(10), k(11); 31 | a.next = &b; b.next = &c; c.next = &d; d.next = &e; e.next = &f; f.next = &g; 32 | g.next = &h; h.next = &i; i.next = &j; j.next = &k; k.next = &d; 33 | ListNode *start = getLoopFront(&a); 34 | cout << start->val << endl; 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /CC150/chap2/removeDuplicate.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | struct ListNode { 5 | int val; 6 | ListNode *next; 7 | ListNode(int x) { val = x; next = nullptr; } 8 | }; 9 | 10 | bool isDup(ListNode *cur, ListNode *p) { 11 | while(p != nullptr && p != cur) { 12 | if(p->val == cur->val) return true; 13 | p = p->next; 14 | } 15 | return false; 16 | } 17 | 18 | ListNode *removeDuplicate(ListNode *head) { 19 | if(head == nullptr || head->next == nullptr) return head; 20 | ListNode *p, *cur=head->next, *pre=head; 21 | while(cur != nullptr) { 22 | // skip dup node 23 | if(isDup(cur, head)) { 24 | pre->next = cur->next; 25 | // pre should not change in this case 26 | cur = cur->next; 27 | } else { 28 | pre = cur; 29 | cur = cur->next; 30 | } 31 | } 32 | return head; 33 | } 34 | 35 | int main() { 36 | ListNode *head = new ListNode(1); 37 | head->next = new ListNode(2); 38 | head->next->next = new ListNode(2); 39 | head->next->next->next = new ListNode(2); 40 | ListNode *p=removeDuplicate(head); 41 | for(; p!=nullptr; p=p->next) cout << p->val << "->"; 42 | cout << "NULL" << endl; 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /CC150/chap3/minStack.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | template 7 | class minStack { 8 | private: 9 | stack s; 10 | stack m; 11 | public: 12 | void push(T x) { 13 | s.push(x); 14 | if(m.empty() || x < m.top()) { 15 | m.push(x); 16 | } 17 | /*else { 18 | m.push(m.top()); 19 | }*/ 20 | } 21 | void pop() { 22 | if(s.top() == min()){ 23 | m.pop(); 24 | } 25 | s.pop(); 26 | } 27 | T top() { 28 | return s.top(); 29 | } 30 | T min() { 31 | if(m.empty()) return INT_MAX; 32 | else return m.top(); 33 | } 34 | }; 35 | 36 | int main() { 37 | minStack s; 38 | cout << s.min() << endl; 39 | s.push(5); 40 | cout << s.min() << endl; 41 | s.push(6); 42 | cout << s.min() << endl; 43 | s.push(3); 44 | cout << s.min() << endl; 45 | s.push(7); 46 | cout << s.min() << endl; 47 | s.pop(); 48 | cout << s.min() << endl; 49 | s.pop(); 50 | cout << s.min() << endl; 51 | } 52 | -------------------------------------------------------------------------------- /CC150/chap3/sortStack.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | void sortStack(stack& a, stack &b) { 6 | if(a.empty() || a.size() <= 1) return; 7 | int n = a.size(); // elements need sort 8 | 9 | while(n>=1) { 10 | int minv = a.top(); 11 | for(int i=0; i x) minv = x; 15 | b.push(x); 16 | } 17 | bool removed = false; 18 | a.push(minv); 19 | while(!b.empty()) { 20 | int x = b.top(); 21 | b.pop(); 22 | if(x != minv || removed) a.push(x); 23 | if(x == minv) removed = true; 24 | } 25 | n -= 1; 26 | } 27 | } 28 | 29 | int main() { 30 | stack a; 31 | stack b; 32 | a.push(1); 33 | a.push(5); 34 | a.push(3); 35 | a.push(3); 36 | a.push(8); 37 | sortStack(a, b); 38 | cout << a.top() << endl; a.pop(); 39 | cout << a.top() << endl; a.pop(); 40 | cout << a.top() << endl; a.pop(); 41 | cout << a.top() << endl; a.pop(); 42 | cout << a.top() << endl; a.pop(); 43 | } 44 | -------------------------------------------------------------------------------- /CC150/chap3/sortStack2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | void sortStack(stack& a) { 6 | stack b; 7 | if(a.empty() || a.size() <= 1) return; 8 | while(!a.empty()) { 9 | int temp = a.top(); 10 | a.pop(); 11 | while(!b.empty() && b.top() > temp) { 12 | a.push(b.top()); 13 | b.pop(); 14 | } 15 | b.push(temp); 16 | } 17 | a = b; 18 | } 19 | 20 | int main() { 21 | stack a; 22 | a.push(1); 23 | a.push(5); 24 | a.push(3); 25 | a.push(3); 26 | a.push(8); 27 | sortStack(a); 28 | cout << a.top() << endl; a.pop(); 29 | cout << a.top() << endl; a.pop(); 30 | cout << a.top() << endl; a.pop(); 31 | cout << a.top() << endl; a.pop(); 32 | cout << a.top() << endl; a.pop(); 33 | } 34 | -------------------------------------------------------------------------------- /CC150/chap5/toBinary.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | string toBinary(double num) { 8 | ostringstream oss; 9 | if(num >= 1 || num <=0) return "ERROR"; 10 | int len = 0; 11 | double r; 12 | while(num > 0) { 13 | if(len >= 32) return "ERROR"; 14 | r = num * 2; 15 | if(r >= 1) { 16 | num = r-1; 17 | oss << 1; 18 | } else { 19 | num = r; 20 | oss << 0; 21 | } 22 | } 23 | return oss.str(); 24 | } 25 | 26 | int main() { 27 | cout << toBinary(0.5) << endl; 28 | cout << toBinary(0.55) << endl; 29 | cout << toBinary(0.75) << endl; 30 | cout << toBinary(0.72) << endl; 31 | cout << toBinary(0.111111111111111111111111111111111) << endl; 32 | cout << toBinary(2.111111111111111111111111111111111) << endl; 33 | } 34 | -------------------------------------------------------------------------------- /CC150/chap7/getKthNum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | int getKthNum(int k) { 8 | if(k < 0) return 0; 9 | queue q3, q5, q7; 10 | q3.push(1); 11 | int value = 0; 12 | for(int i=0; i<=k; i++) { 13 | int v3 = q3.empty() ? INT_MAX : q3.front(); 14 | int v5 = q5.empty() ? INT_MAX : q5.front(); 15 | int v7 = q7.empty() ? INT_MAX : q7.front(); 16 | value = min(v3, min(v5, v7)); 17 | 18 | if(value == v3) { 19 | q3.push(3*value); 20 | q5.push(5*value); 21 | q3.pop(); 22 | } else if(value == v5) { 23 | q5.push(5*value); 24 | q5.pop(); 25 | } else { 26 | q7.pop(); 27 | } 28 | q7.push(7*value); 29 | } 30 | return value; 31 | } 32 | 33 | int main() { 34 | cout << getKthNum(5) << endl; 35 | return 1; 36 | } 37 | -------------------------------------------------------------------------------- /EPI/1501-sort-stock-trade.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Problem 10.1 Design an algorithm that takes a set of files containing sotck trade information 3 | * in sorted order, and writes a single file containing all lines appearing in the individual files 4 | * sorted in sorted order. The algorithm should use very little RAM, ideally of the order of a few 5 | * kilobytes. 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | template 14 | struct cmp { 15 | bool operator() (const pair &a, const pair &b) const { 16 | return a.first > b.first; 17 | } 18 | }; 19 | 20 | template 21 | vector merge_arrays(const vector> &S) { 22 | priority_queue, vector >, cmp > minheap; 23 | vector S_idx(S.size(), 0); 24 | 25 | for (int i = 0; i < S.size(); ++i) { 26 | if (!S[i].empty()) { 27 | // or you can use minheap.emplace(S[i][0], i); 28 | minheap.push(make_pair(S[i][0], i)); 29 | S_idx[i] = 1; 30 | } 31 | } 32 | 33 | vector res; 34 | while (!minheap.empty()) { 35 | pair p = minheap.top(); 36 | res.push_back(p.first); 37 | if (S_idx[p.second] < S[p.second].size()) { 38 | minheap.push(make_pair(S[p.second][S_idx[p.second]], p.second)); 39 | ++S_idx[p.second]; 40 | } 41 | minheap.pop(); 42 | } 43 | 44 | return res; 45 | } 46 | 47 | 48 | int main() { 49 | vector > S = { {1, 2, 3, 4, 5}, 50 | {2, 100, 300, 999}, 51 | {4, 5, 8, 222, 100000} }; 52 | vector res = merge_arrays(S); 53 | for (auto x: res) cout << x << " "; 54 | cout << endl; 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /EPI/build: -------------------------------------------------------------------------------- 1 | if [ -z "$1" ] 2 | then 3 | echo "No argu supplied" 4 | exit 1 5 | fi 6 | name=$1 7 | echo compile and run $name 8 | g++ -c $name.cpp -std=c++11 9 | g++ $name.o -o $name.out 10 | ./$name.out 11 | rm $name.out 12 | rm $name.o 13 | -------------------------------------------------------------------------------- /Geeks4Geeks/README.md: -------------------------------------------------------------------------------- 1 | # Geeks For Geeks 2 | Solutions for problems in http://www.geeksforgeeks.org/ 3 | -------------------------------------------------------------------------------- /Geeks4Geeks/build: -------------------------------------------------------------------------------- 1 | if [ -z "$1" ] 2 | then 3 | echo "No argu supplied" 4 | exit 1 5 | fi 6 | name=$1 7 | echo compile and run $name 8 | g++ -c $name.cpp -std=c++11 9 | g++ $name.o -o $name.out 10 | ./$name.out 11 | rm $name.out 12 | rm $name.o 13 | -------------------------------------------------------------------------------- /Geeks4Geeks/quicksort-on-singly-linked-list.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | struct ListNode { 6 | int val; 7 | ListNode *next; 8 | ListNode(int x) : val(x), next(NULL) {} 9 | }; 10 | 11 | ListNode *quicksort(ListNode *head, ListNode **tail) { 12 | if (head == nullptr || head->next == nullptr) { 13 | *tail = head; 14 | return head; 15 | } 16 | ListNode d1(-1), d2(-1); 17 | ListNode *pivot = head, *p = head->next; 18 | while (p != nullptr) { 19 | ListNode *next = p->next; 20 | ListNode *tmp = nullptr; 21 | if (p->val < pivot->val) { 22 | tmp = d1.next; 23 | d1.next = p; 24 | } else { 25 | tmp = d2.next; 26 | d2.next = p; 27 | } 28 | p->next = tmp; 29 | p = next; 30 | } 31 | ListNode *t1 = nullptr, *t2 = nullptr; 32 | ListNode *h1 = quicksort(d1.next, &t1); 33 | ListNode *h2 = quicksort(d2.next, &t2); 34 | if (t1 != nullptr) t1->next = pivot; 35 | *tail = pivot; 36 | pivot->next = h2; 37 | if (t2 != nullptr) *tail = t2; 38 | return h1 == nullptr ? pivot : h1; 39 | } 40 | 41 | void print(ListNode *head) { 42 | for (ListNode *p = head; p; p = p->next) { 43 | cout << p->val << " -> "; 44 | } 45 | cout << "nullptr" << endl; 46 | } 47 | 48 | int main() { 49 | ListNode* head = new ListNode(4); 50 | ListNode* p = head; 51 | vector v { 3,4,5,2,3,6,7,9,4,5,2,5,6,3,1 }; 52 | for (auto a : v) { 53 | p->next = new ListNode(a); 54 | p = p->next; 55 | } 56 | print(head); 57 | ListNode *tail; 58 | head = quicksort(head, &tail); 59 | print(head); 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /LeetCode/3sum-closest.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int threeSumClosest(vector &num, int target) { 4 | int res = INT_MAX; 5 | if (num.size() < 3) return res; 6 | sort(num.begin(), num.end()); 7 | 8 | int min_gap = INT_MAX; 9 | for (auto a = num.begin(); a < prev(num.end(), 2); ++a) { 10 | if (a != num.begin() && *a == *prev(a)) continue; 11 | auto b = a + 1; 12 | auto c = num.end() - 1; 13 | while (b < c) { 14 | int sum = *a + *b + *c; 15 | int gap = abs(sum - target); 16 | if (gap < min_gap) { 17 | min_gap = gap; 18 | res = sum; 19 | if (min_gap == 0) return res; 20 | } 21 | if (sum < target) ++b; 22 | else --c; 23 | } 24 | } 25 | return res; 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /LeetCode/3sum.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector > threeSum(vector &num) { 4 | vector > res; 5 | if (num.size() <= 2) return res; 6 | 7 | sort(num.begin(), num.end()); 8 | for (auto a = num.begin(); a != prev(num.end(), 2); ++a) { 9 | if (a != num.begin() && *a == *prev(a)) continue; 10 | auto b = next(a); 11 | auto c = prev(num.end()); 12 | while (b < c) { 13 | if (*a + *b + *c == 0) { 14 | vector temp; 15 | temp.push_back(*a); 16 | temp.push_back(*b); 17 | temp.push_back(*c); 18 | res.push_back(temp); 19 | b++; 20 | c--; 21 | while (b < c && *prev(b) == *b) ++b; 22 | } else if (*a + *b + *c < 0) { 23 | b++; 24 | } else { 25 | c--; 26 | } 27 | } 28 | } 29 | // remvoe duplicate 30 | // sort(res.begin(), res.end()); 31 | // res.erase(unique(res.begin(), res.end()), res.end()); 32 | return res; 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /LeetCode/4sum.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector > fourSum(vector &num, int target) { 4 | vector > res; 5 | if (num.size() <= 3) return res; 6 | sort(num.begin(), num.end()); 7 | auto last = num.end(); 8 | for (auto a = num.begin(); a < prev(last, 3); ++a) { 9 | if (a != num.begin() && *a == *prev(a)) continue; 10 | for (auto b = a + 1; b < prev(last, 2); ++b) { 11 | if (b != a + 1 && *b == *prev(b)) continue; 12 | auto c = next(b, 1); 13 | auto d = prev(last, 1); 14 | while (c < d) { 15 | if (*a + *b + *c + *d == target) { 16 | res.push_back({*a, *b, *c, *d}); 17 | ++c; 18 | --d; 19 | while (c < d && *c == *prev(c)) ++c; 20 | } else if (*a + *b + *c + *d < target) { 21 | ++c; 22 | } else { 23 | --d; 24 | } 25 | } 26 | } 27 | } 28 | // remove duplicate 29 | // sort(res.begin(), res.end()); 30 | // res.erase(unique(res.begin(),res.end()), res.end()); 31 | return res; 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /LeetCode/README.md: -------------------------------------------------------------------------------- 1 | #LeetCode 2 | Here are the list of all the problems: [LeetCode OJ](https://oj.leetcode.com/problems/). 3 | 4 | Solve all the problems with C++11. Try writing neat code in a short time. 5 | -------------------------------------------------------------------------------- /LeetCode/add-binary.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | string addBinary(string a, string b) { 4 | ostringstream oss; 5 | int c = 0; 6 | for (int i = 0; i < a.size() && i || i < b.size() || c > 0; ++i) { 7 | int inta = i < a.size() ? a[a.size() - i - 1] - '0' : 0; 8 | int intb = i < b.size() ? b[b.size() - i - 1] - '0' : 0; 9 | int sum = inta + intb + c; 10 | c = sum / 2; 11 | oss << sum % 2; 12 | } 13 | string res = oss.str(); 14 | reverse(res.begin(), res.end()); 15 | return res; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /LeetCode/add-two-numbers.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | ListNode *addTwoNumbers(ListNode *l1, ListNode *l2) { 4 | ListNode dumpy(-1); 5 | ListNode *p = &dumpy; 6 | int c = 0, a, b, res; 7 | while (l1 || l2 || c) { 8 | a = l1 == nullptr ? 0 : l1->val; 9 | b = l2 == nullptr ? 0 : l2->val; 10 | res = (a + b + c); 11 | c = res / 10; 12 | p->next = new ListNode(res % 10); 13 | 14 | p = p->next; 15 | if (l1) l1 = l1->next; 16 | if (l2) l2 = l2->next; 17 | } 18 | return dumpy.next; 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /LeetCode/anagrams.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector anagrams(vector &strs) { 4 | unordered_map > dict; 5 | for (int i = 0; i res; 12 | for (auto it = dict.begin(); it != dict.end(); ++it) { 13 | for (auto s : it->second) { 14 | if (it->second.size() <= 1) continue; 15 | res.push_back(s); 16 | } 17 | } 18 | return res; 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /LeetCode/balanced-binary-tree.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | /*int depth(TreeNode *root) { 4 | if (root == nullptr) return 0; 5 | return max(depth(root->left), depth(root->right)) + 1; 6 | }*/ 7 | 8 | int depth(TreeNode *root) { 9 | if (root == nullptr) return 0; 10 | int left_len = depth(root->left); 11 | int right_len = depth(root->right); 12 | if (left_len < 0 || right_len < 0 || abs(left_len - right_len) > 1) return -1; 13 | return max(left_len, right_len) + 1; 14 | } 15 | 16 | bool isBalanced(TreeNode *root) { 17 | if (root == nullptr) return true; 18 | //return (isBalanced(root->left) && isBalanced(root->right) && abs(depth(root->left) - depth(root->right)) <= 1); 19 | return depth(root) != -1; 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /LeetCode/best-time-to-buy-and-sell-stock-ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maxProfit(vector &prices) { 4 | int res = 0; 5 | if (prices.empty()) return 0; 6 | int min_price = prices[0]; 7 | for (int i = 1; i < prices.size(); ++i) { 8 | if (prices[i] > min_price) { 9 | res += (prices[i] - min_price); 10 | } 11 | min_price = prices[i]; 12 | } 13 | return res; 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /LeetCode/best-time-to-buy-and-sell-stock-iii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maxProfit(vector &prices) { 4 | int n = prices.size(); 5 | if(n <= 1) return 0; 6 | vector f(n, 0), b(n, 0); 7 | int cur_min = prices[0]; 8 | int max_gap = 0; 9 | for (int i = 1; i < n; ++i) { 10 | cur_min = min(cur_min, prices[i]); 11 | max_gap = max(max_gap, prices[i] - cur_min); 12 | f[i] = max_gap; 13 | } 14 | int cur_max = prices[n-1]; 15 | max_gap = 0; 16 | for (int i = n-2; i >= 0; --i) { 17 | cur_max = max(cur_max, prices[i]); 18 | max_gap = max(max_gap, cur_max - prices[i]); 19 | b[i] = max_gap; 20 | } 21 | 22 | int res = 0; 23 | for (int i = 0; i < n; ++i) { 24 | res = max(res, f[i] + b[i]); 25 | } 26 | return res; 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /LeetCode/best-time-to-buy-and-sell-stock.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maxProfit(vector &prices) { 4 | if (prices.empty()) return 0; 5 | int res = 0, min_price = prices[0], max_price = prices[0]; 6 | for (auto p: prices) { 7 | min_price = min(min_price, p); 8 | res = max(res, p - min_price); 9 | } 10 | return res; 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /LeetCode/binary-tree-inorder-traversal.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector inorderTraversal(TreeNode *root) { 4 | vector res; 5 | TreeNode *cur = root; 6 | stack s; 7 | 8 | while (!s.empty() || cur != nullptr) { 9 | if (cur != nullptr) { 10 | s.push(cur); 11 | cur = cur->left; 12 | } else { 13 | cur = s.top(); 14 | s.pop(); 15 | res.push_back(cur->val); 16 | cur = cur->right; 17 | } 18 | } 19 | return res; 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /LeetCode/binary-tree-level-order-traversal-ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector > levelOrderBottom(TreeNode *root) { 4 | vector > res; 5 | if (root == nullptr) return res; 6 | queue current, next; 7 | current.push(root); 8 | vector path; 9 | while (!current.empty()) { 10 | while (!current.empty()) { 11 | TreeNode *p = current.front(); 12 | current.pop(); 13 | path.push_back(p->val); 14 | if (p->left) next.push(p->left); 15 | if (p->right) next.push(p->right); 16 | } 17 | res.push_back(path); 18 | path.clear(); 19 | current.swap(next); 20 | } 21 | reverse(res.begin(), res.end()); 22 | return res; 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /LeetCode/binary-tree-level-order-traversal.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector > levelOrder(TreeNode *root) { 4 | vector > res; 5 | if (root == nullptr) return res; 6 | queue current, next; 7 | current.push(root); 8 | vector path; 9 | while (!current.empty()) { 10 | while (!current.empty()) { 11 | TreeNode *p = current.front(); 12 | current.pop(); 13 | path.push_back(p->val); 14 | if (p->left) next.push(p->left); 15 | if (p->right) next.push(p->right); 16 | } 17 | res.push_back(path); 18 | path.clear(); 19 | current.swap(next); 20 | } 21 | return res; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /LeetCode/binary-tree-maximum-path-sum.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maxPathSum(TreeNode *root) { 4 | max_sum = INT_MIN; 5 | dfs(root); 6 | return max_sum; 7 | } 8 | 9 | private: 10 | int max_sum; 11 | int dfs(TreeNode *root){ 12 | if (root == NULL) return 0; 13 | int l = dfs(root->left); 14 | int r = dfs(root->right); 15 | int sum=root->val; 16 | if (l > 0) sum+=l; 17 | if (r > 0) sum+=r; 18 | if (sum > max_sum) max_sum = sum; 19 | return max(l,r)>0 ? max(l,r) + root->val : root->val; 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /LeetCode/binary-tree-postorder-traversal.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for binary tree 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 | * }; 9 | */ 10 | class Solution { 11 | public: 12 | vector postorderTraversal(TreeNode *root) { 13 | vector res; 14 | stack s; 15 | TreeNode *p = root, *q; 16 | if (root == nullptr) return res; 17 | 18 | do { 19 | while (p != nullptr) { 20 | s.push(p); 21 | p = p->left; 22 | } 23 | q = nullptr; 24 | while (!s.empty()) { 25 | p = s.top(); 26 | if (p->right == q) { // right child visited 27 | s.pop(); 28 | res.push_back(p->val); 29 | q = p; // last visited member 30 | } else { 31 | p = p->right; 32 | break; 33 | } 34 | } 35 | } while (!s.empty()); 36 | return res; 37 | } 38 | }; -------------------------------------------------------------------------------- /LeetCode/binary-tree-preorder-traversal.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for binary tree 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 | * }; 9 | */ 10 | class Solution { 11 | public: 12 | vector preorderTraversal(TreeNode *root) { 13 | vector res; 14 | if (root == nullptr) return res; 15 | stack s; 16 | s.push(root); 17 | while (!s.empty()) { 18 | TreeNode *p = s.top(); 19 | s.pop(); 20 | res.push_back(p->val); 21 | if (p->right) s.push(p->right); 22 | if (p->left) s.push(p->left); 23 | } 24 | return res; 25 | } 26 | }; -------------------------------------------------------------------------------- /LeetCode/binary-tree-zigzag-level-order-traversal.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector > zigzagLevelOrder(TreeNode *root) { 4 | vector > res; 5 | if(root == nullptr) return res; 6 | queue current, next; 7 | bool direction = false; 8 | current.push(root); 9 | vector path; 10 | while (!current.empty()) { 11 | while (!current.empty()) { 12 | TreeNode *p = current.front(); 13 | current.pop(); 14 | path.push_back(p->val); 15 | if (p->left != nullptr) next.push(p->left); 16 | if (p->right != nullptr) next.push(p->right); 17 | } 18 | if (direction) { 19 | reverse(path.begin(), path.end()); 20 | } 21 | direction = !direction; 22 | res.push_back(path); 23 | current.swap(next); 24 | path.clear(); 25 | } 26 | return res; 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /LeetCode/candy.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int candy(vector &ratings) { 4 | if (ratings.empty()) return 0; 5 | int n = ratings.size(); 6 | vector score(n, 1); 7 | int pre = 1; 8 | for (int i = 1; i < n; ++i) { 9 | if (ratings[i] > ratings[i-1]) { 10 | pre += 1; 11 | score[i] = pre; 12 | } else { 13 | pre = 1; 14 | } 15 | } 16 | for (int i = n-2; i >= 0; --i) { 17 | if (ratings[i] > ratings[i+1]) { 18 | pre += 1; 19 | score[i] = max(score[i], pre); 20 | } else { 21 | pre = 1; 22 | } 23 | } 24 | return accumulate(score.begin(), score.end(), 0); 25 | } 26 | 27 | }; 28 | -------------------------------------------------------------------------------- /LeetCode/climbing-stairs.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int climbStairs(int n) { 4 | if (n <= 1) return 1; 5 | int pre1 = 1, pre2 = 1, cur = 1; 6 | for (int i = 2; i <= n; ++i) { 7 | cur = pre1 + pre2; 8 | pre2 = pre1; 9 | pre1 = cur; 10 | } 11 | return cur; 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /LeetCode/clone-graph.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for undirected graph. 3 | * struct UndirectedGraphNode { 4 | * int label; 5 | * vector neighbors; 6 | * UndirectedGraphNode(int x) : label(x) {}; 7 | * }; 8 | */ 9 | class Solution { 10 | public: 11 | UndirectedGraphNode *cloneGraph(UndirectedGraphNode *node) { 12 | if(node == nullptr) return node; 13 | unordered_map nmap; 14 | queue q; 15 | q.push(node); 16 | while (!q.empty()) { 17 | UndirectedGraphNode *p = q.front(); 18 | q.pop(); 19 | if (nmap.find(p) != nmap.end()) continue; 20 | 21 | nmap[p] = new UndirectedGraphNode(p->label); 22 | for (auto neighbor: p->neighbors) { 23 | if (nmap.find(neighbor) == nmap.end()) q.push(neighbor); 24 | } 25 | } 26 | for (auto it = nmap.begin(); it != nmap.end(); ++it) { 27 | for (auto neighbor: it->first->neighbors) { 28 | nmap[it->first]->neighbors.push_back(nmap[neighbor]); 29 | } 30 | } 31 | return nmap[node]; 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /LeetCode/combination-sum-ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector > combinationSum2(vector &num, int target) { 4 | vector > res; 5 | if (num.empty()) return res; 6 | sort(num.begin(), num.end()); 7 | vector path; 8 | dfs(num, 0, 0, target, path, res); 9 | return res; 10 | } 11 | 12 | void dfs(vector &candidates, int sum, int start, int target, vector &path, vector > &res) { 13 | if (sum > target) return; 14 | if (target == sum) { 15 | res.push_back(path); 16 | return; 17 | } 18 | for (int i = start; i < candidates.size(); i++) { 19 | if(i > start && candidates[i] == candidates[i-1]) continue; 20 | path.push_back(candidates[i]); 21 | dfs(candidates, sum+candidates[i], i+1, target, path, res); 22 | path.pop_back(); 23 | } 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /LeetCode/combination-sum.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector > combinationSum(vector &candidates, int target) { 4 | vector > res; 5 | if(candidates.empty()) return res; 6 | sort(candidates.begin(), candidates.end()); 7 | vector path; 8 | dfs(candidates, 0, 0, target, path, res); 9 | return res; 10 | } 11 | 12 | void dfs(vector &candidates, int sum, int start, int target, vector &path, vector > &res) { 13 | if (sum > target) return; 14 | if (target == sum) { 15 | res.push_back(path); 16 | return; 17 | } 18 | for (int i = start; i < candidates.size(); ++i) { 19 | path.push_back(candidates[i]); 20 | dfs(candidates, sum+candidates[i], i, target, path, res); 21 | path.pop_back(); 22 | } 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /LeetCode/combinations.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector > combine(int n, int k) { 4 | vector > res; 5 | vector path; 6 | vector used(n+1, false); 7 | dfs(res, path, used, n, 0, k, 0); 8 | return res; 9 | } 10 | 11 | void dfs(vector > &res, vector &path, vector &used, int n, int level, int k, int pre) 12 | { 13 | if (level == k) { 14 | res.push_back(path); 15 | return; 16 | } 17 | for (int i = pre + 1; i <= n; ++i) { 18 | if(used[i]) continue; 19 | used[i] = true; 20 | path.push_back(i); 21 | dfs(res, path, used, n, level+1, k, i); 22 | path.pop_back(); 23 | used[i] = false; 24 | } 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /LeetCode/construct-binary-tree-from-inorder-and-postorder-traversal.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | TreeNode *buildTree(vector &inorder, vector &postorder) { 4 | return buildTree(inorder.begin(), inorder.end(), postorder.begin(), postorder.end()); 5 | } 6 | 7 | template 8 | TreeNode *buildTree(BidIt inbegin, BidIt inend, BidIt postbegin, BidIt postend) { 9 | if (postbegin == postend || inbegin == inend) return nullptr; 10 | auto rit = prev(postend); 11 | TreeNode *root = new TreeNode(*rit); 12 | 13 | auto rit_in = find(inbegin, inend, *rit); 14 | int len = distance(inbegin, rit_in); 15 | root->left = buildTree(inbegin, rit_in, postbegin, next(postbegin, len)); 16 | root->right = buildTree(rit_in + 1, inend, next(postbegin, len), postend-1); 17 | return root; 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /LeetCode/construct-binary-tree-from-preorder-and-inorder-traversal.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | TreeNode *buildTree(vector &preorder, vector &inorder) { 4 | return buildTree(preorder.begin(), preorder.end(), inorder.begin(), inorder.end()); 5 | } 6 | 7 | template 8 | TreeNode *buildTree(BidiIt prefirst, BidiIt prelast, BidiIt infirst, BidiIt inlast) { 9 | if (prefirst == prelast || infirst == inlast) return nullptr; 10 | TreeNode *root = new TreeNode(*prefirst); 11 | auto rit = find(infirst, inlast, *prefirst); 12 | int len = distance(infirst, rit); 13 | root->left = buildTree(prefirst+1, next(prefirst, len+1), infirst, next(infirst, len)); 14 | root->right = buildTree(next(prefirst, len+1), prelast, next(infirst, len+1), inlast); 15 | return root; 16 | } 17 | 18 | }; 19 | -------------------------------------------------------------------------------- /LeetCode/container-with-most-water.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maxArea(vector &height) { 4 | int start = 0; 5 | int end = height.size() - 1; 6 | int res = 0; 7 | while (start < end) { 8 | res = max(res, min(height[start], height[end]) * (end-start)); 9 | if (height[start] < height[end]) { 10 | ++start; 11 | } else { 12 | --end; 13 | } 14 | } 15 | return res; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /LeetCode/convert-sorted-array-to-binary-search-tree.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | TreeNode *sortedArrayToBST(vector &num) { 4 | return sortedArrayToBST(num.begin(), num.end()); 5 | } 6 | 7 | template 8 | TreeNode *sortedArrayToBST(BidIt start, BidIt end) { 9 | if (start == end) return nullptr; 10 | auto mid = start + distance(start, end) / 2; 11 | TreeNode *root = new TreeNode(*mid); 12 | root->left = sortedArrayToBST(start, mid); 13 | root->right = sortedArrayToBST(mid+1, end); 14 | return root; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /LeetCode/convert-sorted-list-to-binary-search-tree.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | TreeNode *sortedListToBST(ListNode *head) { 4 | if (head == nullptr) return nullptr; 5 | ListNode *pre_mid = nullptr; 6 | ListNode *slow = head, *fast = head; 7 | while (fast->next && fast->next->next) { 8 | pre_mid = slow; 9 | slow = slow->next; 10 | fast = fast->next->next; 11 | } 12 | 13 | TreeNode *root = new TreeNode(slow->val); 14 | if (pre_mid) { 15 | pre_mid->next = nullptr; 16 | root->left = sortedListToBST(head); 17 | } 18 | root->right = sortedListToBST(slow->next); 19 | return root; 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /LeetCode/copy-list-with-random-pointer.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | RandomListNode *copyRandomList(RandomListNode *head) { 4 | if (head == nullptr) return nullptr; 5 | RandomListNode *p = head, *next; 6 | RandomListNode *newp; 7 | while (p) { 8 | next = p->next; 9 | newp = new RandomListNode(p->label); 10 | 11 | p->next = newp; 12 | newp->next = next; 13 | p = next; 14 | } 15 | // Now deal with the random field 16 | for (p = head; p; p = p->next->next) { 17 | if (p->random != nullptr) p->next->random = p->random->next; 18 | } 19 | // Now recover the next filed 20 | p = head; 21 | newp = p->next; 22 | RandomListNode *res = newp; 23 | while (p != nullptr) { 24 | p->next = newp->next; 25 | if (newp->next == nullptr) break; 26 | newp->next = newp->next->next; 27 | p = p->next; 28 | newp = newp->next; 29 | } 30 | return res; 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /LeetCode/count-and-say.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | string countAndSay(int n) { 4 | string str = "1"; 5 | for (int i = 1; i < n; ++i) { 6 | char cur = str[0]; 7 | int cnt = 1; 8 | ostringstream oss; 9 | for (int j = 1; j < str.size(); ++j) { 10 | if (str[j] == cur) { 11 | ++cnt; 12 | } else { 13 | oss << cnt << cur; 14 | cur = str[j]; 15 | cnt = 1; 16 | } 17 | } 18 | oss << cnt << cur; 19 | str = oss.str(); 20 | } 21 | return str; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /LeetCode/decode-ways.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int numDecodings(string s) { 4 | if (s.empty()) return 0; 5 | int n = s.size(); 6 | vector f(n + 1, 0); 7 | f[0] = 1; 8 | f[1] = s[0] == '0' ? 0 : 1; 9 | for (int l = 2; l <= n; ++l) { 10 | f[l] = s[l-1] == '0' ? 0 : f[l-1]; 11 | if (s[l-2] == '1' || s[l-2] == '2' && s[l-1] <= '6') f[l] += f[l-2]; 12 | } 13 | return f[n]; 14 | } 15 | }; -------------------------------------------------------------------------------- /LeetCode/distinct-subsequences.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int numDistinct(string S, string T) { 4 | int m = S.size(); 5 | int n = T.size(); 6 | vector f(n+1, 0); 7 | f[0] = 1; 8 | for (int i = 0; i < m; ++i) { 9 | for (int j = min(n - 1, i); j >= 0; --j) { 10 | f[j+1] += (S[i] == T[j]) ? f[j] : 0; 11 | } 12 | } 13 | return f[n]; 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /LeetCode/divide-two-integers.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int divide(int dividend, int divisor) { 4 | bool neg = false; 5 | long long a = dividend, b = divisor; 6 | if (dividend < 0) { 7 | neg = !neg; 8 | a = -a; 9 | } 10 | if (divisor < 0) { 11 | neg = !neg; 12 | b = -b; 13 | } 14 | int res = 0; 15 | while (a >= b) { 16 | long long m = b; 17 | for (int i = 0; a >= m; i++) { 18 | a -= m; 19 | res += (1 << i); 20 | m = m << 1; 21 | } 22 | } 23 | return neg ? -res : res; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /LeetCode/edit-distance.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int minDistance(string word1, string word2) { 4 | int m = word1.size(); 5 | int n = word2.size(); 6 | vector > f(m+1, vector(n+1, 1)); 7 | for (int i = 0; i <= m; ++i) f[i][0] = i; 8 | for (int j = 0; j <= n; ++j) f[0][j] = j; 9 | for (int i = 1; i <= m; ++i) { 10 | for (int j = 1; j <= n; ++j) { 11 | f[i][j] = word1[i-1] == word2[j-1] ? f[i-1][j-1] : f[i-1][j-1] + 1; 12 | f[i][j] = min(f[i][j], f[i-1][j] + 1); 13 | f[i][j] = min(f[i][j], f[i][j-1] + 1); 14 | } 15 | } 16 | return f[m][n]; 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /LeetCode/evaluate-reverse-polish-notation.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool isoperator(const string &x) { 4 | return x == "+" || x == "-" || x == "*" || x == "/"; 5 | } 6 | 7 | int evalRPN(vector &tokens) { 8 | stack s; 9 | int res = 0; 10 | if (tokens.empty()) return 0; 11 | for (auto x: tokens) { 12 | if (isoperator(x)) { 13 | int b = s.top(); 14 | s.pop(); 15 | int a = s.top(); 16 | s.pop(); 17 | if (x == "+") s.push(a + b); 18 | else if(x == "-") s.push(a - b); 19 | else if(x == "*") s.push(a * b); 20 | else if(x == "/") s.push(a / b); 21 | } else { 22 | s.push(atoi(x.c_str())); 23 | } 24 | } 25 | return s.top(); 26 | } 27 | }; -------------------------------------------------------------------------------- /LeetCode/first-missing-positive.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int firstMissingPositive(int A[], int n) { 4 | for (int i = 0; i < n; ++i) { 5 | while (A[i] != i + 1 && A[i] <= n && A[i] > 0 && A[i] != A[A[i]-1]) swap(A[i], A[A[i]-1]); 6 | } 7 | for (int i = 0; i < n; ++i) { 8 | if (A[i] != i + 1) return i + 1; 9 | } 10 | return n + 1; 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /LeetCode/flatten-binary-tree-to-linked-list.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void flatten(TreeNode *root) { 4 | if(root == nullptr) return; 5 | if(root->left == nullptr && root->right == nullptr) return; 6 | 7 | flatten(root->left); 8 | flatten(root->right); 9 | 10 | TreeNode *tmp = root->right; 11 | root->right = root->left; 12 | root->left = nullptr; 13 | // find the last right 14 | TreeNode *p = root; 15 | while (p->right) p = p->right; 16 | p->right = tmp; 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /LeetCode/gas-station.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int canCompleteCircuit(vector &gas, vector &cost) { 4 | int start = 0, end = gas.size(); 5 | int tank = 0, res = 0; 6 | while (start < end) { 7 | tank += gas[start] - cost[start]; 8 | ++start; 9 | while (tank < 0 && start < end) { 10 | --end; 11 | tank += gas[end] - cost[end]; 12 | res = end; 13 | } 14 | } 15 | return (tank >= 0) ? res : -1; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /LeetCode/generate-parentheses.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector generateParenthesis(int n) { 4 | vector res; 5 | string path = ""; 6 | generate(0, 0, n, path, res); 7 | return res; 8 | } 9 | 10 | void generate(int left, int right, int n, string path, vector &res) { 11 | if (path.size() == n * 2) { 12 | res.push_back(path); 13 | return; 14 | } 15 | if(left < n) generate(left + 1, right, n, path + '(', res); 16 | if(left > right) generate(left, right + 1, n, path + ')', res); 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /LeetCode/gray-code.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector grayCode(int n) { 4 | vector res; 5 | if (n == 0) return {0}; 6 | res = {0, 1}; 7 | int x = 1; 8 | for (int i = 2; i <= n; ++i) { 9 | x *= 2; 10 | for (int j = res.size() - 1; j >= 0; --j) { 11 | res.push_back(res[j] + x); 12 | } 13 | } 14 | return res; 15 | } 16 | }; -------------------------------------------------------------------------------- /LeetCode/implement-strstr.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool compare(char *a, char *b, int n) { 4 | for (int i = 0; i < n; ++i) if (a[i] != b[i]) return false; 5 | return true; 6 | } 7 | 8 | char *strStr(char *haystack, char *needle) { 9 | size_t len = strlen(haystack); 10 | size_t nlen = strlen(needle); 11 | if (nlen == 0) return haystack; 12 | if (nlen > len) return nullptr; 13 | if (nlen == len) return compare(haystack, needle, len) ? haystack : nullptr; 14 | for (unsigned int i = 0; i <= len - nlen ; ++i) { 15 | char *cur = haystack + i; 16 | if (compare(cur, needle, nlen)) return cur; 17 | } 18 | return nullptr; 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /LeetCode/insert-interval.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for an interval. 3 | * struct Interval { 4 | * int start; 5 | * int end; 6 | * Interval() : start(0), end(0) {} 7 | * Interval(int s, int e) : start(s), end(e) {} 8 | * }; 9 | */ 10 | class Solution { 11 | public: 12 | vector insert(vector &intervals, Interval newInterval) { 13 | auto it = intervals.begin(); 14 | while (it != intervals.end()) { 15 | if (newInterval.end < it->start) { 16 | // insert before it 17 | intervals.insert(it, newInterval); 18 | return intervals; 19 | } else if (newInterval.start <= it->end){ 20 | // included in it 21 | if (newInterval.start >= it->start && newInterval.end <= it->end) return intervals; 22 | // overlap 23 | newInterval.start = min(it->start, newInterval.start); 24 | newInterval.end = max(it->end, newInterval.end); 25 | it = intervals.erase(it); 26 | } else ++it; 27 | } 28 | intervals.push_back(newInterval); 29 | return intervals; 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /LeetCode/insertion-sort-list.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for singly-linked list. 3 | * struct ListNode { 4 | * int val; 5 | * ListNode *next; 6 | * ListNode(int x) : val(x), next(NULL) {} 7 | * }; 8 | */ 9 | class Solution { 10 | public: 11 | ListNode *insertionSortList(ListNode *head) { 12 | if (head == nullptr || head->next == nullptr) return head; 13 | ListNode dumpy(-1); 14 | ListNode *next = head, *p = nullptr; 15 | while (next) { 16 | p = next; 17 | next = p->next; 18 | p->next = nullptr; 19 | 20 | // insert node p to the new list 21 | ListNode *pre = &dumpy; 22 | ListNode *q = dumpy.next; 23 | while (q != nullptr) { 24 | if (q->val > p->val) break; 25 | pre = q; 26 | q = q->next; 27 | } 28 | pre->next = p; 29 | p->next = q; 30 | } 31 | return dumpy.next; 32 | } 33 | }; -------------------------------------------------------------------------------- /LeetCode/integer-to-roman.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | string intToRoman(int num) { 4 | // I(1) V(5) X(10) L(50) C(100) D(500) M(1000) 5 | const int radix[] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}; 6 | const string symbols[] = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"}; 7 | 8 | string result; 9 | for (int i = 0; num > 0; ++i) { 10 | int c = num / radix[i]; 11 | num %= radix[i]; 12 | while (c > 0) { 13 | result += symbols[i]; 14 | c--; 15 | } 16 | } 17 | return result; 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /LeetCode/jump-game-ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int jump(int A[], int n) { 4 | int cur = 0, last = 0; 5 | int step = 0; 6 | for (int i = 0; i < n; i++) { 7 | if (i > last) { 8 | last = cur; 9 | ++step; 10 | } 11 | cur = max(cur, i + A[i]); 12 | } 13 | return step; 14 | } 15 | 16 | /*int jump(int A[], int n) { 17 | int curlen = 1, nextlen = 0; 18 | int step = 0; 19 | int i = 0; 20 | while (curlen != 0) { 21 | while (curlen != 0) { 22 | --curlen; 23 | --nextlen; 24 | nextlen = max(nextlen, A[i]); 25 | if (i == n - 1) return step; 26 | ++i; 27 | } 28 | curlen = nextlen; 29 | nextlen = 0; 30 | ++step; 31 | } 32 | return -1; 33 | }*/ 34 | }; 35 | -------------------------------------------------------------------------------- /LeetCode/jump-game.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool canJump(int A[], int n) { 4 | int maxlen = 1; 5 | for (int i = 0; i < n; ++i) { 6 | if (maxlen == 0) return false; 7 | --maxlen; 8 | maxlen = max(maxlen, A[i]); 9 | } 10 | return true; 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /LeetCode/largest-rectangle-in-histogram.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int largestRectangleArea(vector &height) { 4 | int res = 0; 5 | height.push_back(0); 6 | stack s; 7 | int i = 0; 8 | while (i < height.size()) { 9 | if (s.empty() || height[i] > height[s.top()]) { 10 | s.push(i++); 11 | } else { 12 | int tmp = s.top(); 13 | s.pop(); 14 | int width = s.empty() ? i : (i - s.top() - 1); 15 | res = max(res, width * height[tmp]); 16 | } 17 | } 18 | return res; 19 | } 20 | }; -------------------------------------------------------------------------------- /LeetCode/length-of-last-word.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int lengthOfLastWord(const char *s) { 4 | int wordlen = 0; 5 | int i = strlen(s) - 1; 6 | while (i >= 0 && s[i] == ' ') --i; 7 | while (i >= 0 && s[i] != ' ') { 8 | --i; 9 | ++wordlen; 10 | } 11 | return wordlen; 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /LeetCode/letter-combinations-of-a-phone-number.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void combine(vector &input, vector &output, string a) { 4 | for (auto c: a) 5 | for (auto x: input) 6 | output.push_back(x + c); 7 | } 8 | 9 | vector letterCombinations(string digits) { 10 | vector input, output(1, ""); 11 | vector dmap = { "abc", "def", "ghi", "jkl", "mno", 12 | "pqrs", "tuv", "wxyz" }; 13 | for (int i = 0; i < digits.size(); ++i) { 14 | input = output; 15 | vector().swap(output); 16 | combine(input, output, dmap[digits[i] - '2']); 17 | } 18 | return output; 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /LeetCode/linked-list-cycle-ii.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for singly-linked list. 3 | * struct ListNode { 4 | * int val; 5 | * ListNode *next; 6 | * ListNode(int x) : val(x), next(NULL) {} 7 | * }; 8 | */ 9 | class Solution { 10 | public: 11 | ListNode *detectCycle(ListNode *head) { 12 | if (head == nullptr) return head; 13 | ListNode *slow = head, *fast = head; 14 | while (fast->next && fast->next->next) { 15 | fast = fast->next->next; 16 | slow = slow->next; 17 | // circle dected 18 | if (slow == fast) { 19 | slow = head; 20 | while (slow != fast) { 21 | slow = slow->next; 22 | fast = fast->next; 23 | } 24 | return slow; 25 | } 26 | } 27 | return nullptr; 28 | } 29 | }; -------------------------------------------------------------------------------- /LeetCode/linked-list-cycle.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for singly-linked list. 3 | * struct ListNode { 4 | * int val; 5 | * ListNode *next; 6 | * ListNode(int x) : val(x), next(NULL) {} 7 | * }; 8 | */ 9 | class Solution { 10 | public: 11 | bool hasCycle(ListNode *head) { 12 | if (head == nullptr) return false; 13 | ListNode *slow = head, *fast = head; 14 | while (fast->next && fast->next->next) { 15 | fast = fast->next->next; 16 | slow = slow->next; 17 | if (slow == fast) return true; 18 | } 19 | return false; 20 | } 21 | }; -------------------------------------------------------------------------------- /LeetCode/longest-common-prefix.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | string longestCommonPrefix(vector &strs) { 4 | if (strs.empty()) return ""; 5 | int maxlen = 0; 6 | while (true) { 7 | if (strs[0].size() < maxlen + 1) break; 8 | int i; 9 | for (i = 1; i < strs.size(); ++i) { 10 | if (strs[i].size() < maxlen + 1 || strs[i][maxlen] != strs[0][maxlen]) break; 11 | } 12 | if (i == strs.size()) maxlen += 1; 13 | else break; 14 | } 15 | return strs[0].substr(0, maxlen); 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /LeetCode/longest-consecutive-sequence.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int longestConsecutive(vector &num) { 4 | unordered_map visited; 5 | for (auto x: num) visited[x] = false; // not visited 6 | int res = 0, len; 7 | for (auto x: num) { 8 | if (visited[x]) continue; 9 | len = 1; 10 | for (int tmp = x - 1; visited.count(tmp); --tmp) { 11 | visited[tmp] = true; 12 | ++len; 13 | } 14 | for (int tmp = x + 1; visited.count(tmp); ++tmp) { 15 | visited[tmp] = true; 16 | ++len; 17 | } 18 | res = max(res, len); 19 | } 20 | return res; 21 | } 22 | }; -------------------------------------------------------------------------------- /LeetCode/longest-palindromic-substring-manacher.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | string preProcess(string s) { 4 | int n = s.length(); 5 | if (n == 0) return "^$"; 6 | string ret = "^"; 7 | for (int i = 0; i < n; i++) ret += "#" + s.substr(i, 1); 8 | ret += "#$"; 9 | return ret; 10 | } 11 | 12 | string longestPalindrome(string s) { 13 | string T = preProcess(s); 14 | const int n = T.length(); 15 | int P[n]; 16 | int C = 0, R = 0; 17 | for (int i = 1; i < n - 1; i++) { 18 | int i_mirror = 2 * C - i; 19 | P[i] = (R > i) ? min(R - i, P[i_mirror]) : 0; 20 | // Attempt to expand palindrome centered at i 21 | while (T[i + 1 + P[i]] == T[i - 1 - P[i]]) 22 | P[i]++; 23 | // If palindrome centered at i expand past R, 24 | // adjust center based on expanded palindrome. 25 | if (i + P[i] > R) { 26 | C = i; 27 | R = i + P[i]; 28 | } 29 | } 30 | // Find the maximum element in P. 31 | int max_len = 0; 32 | int center_index = 0; 33 | for (int i = 1; i < n - 1; i++) { 34 | if (P[i] > max_len) { 35 | max_len = P[i]; 36 | center_index = i; 37 | 38 | } 39 | } 40 | return s.substr((center_index - 1 - max_len) / 2, max_len); 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /LeetCode/longest-palindromic-substring.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | string longestPalindrome(string s) { 4 | int maxi = 0, maxlen = 0; 5 | if (s.empty()) return ""; 6 | int n = s.size(); 7 | bool p[n][n]; 8 | fill_n(&p[0][0], n*n, false); 9 | 10 | int max_start = 0, max_len = 1; 11 | for (int i = 0; i < n; ++i) { 12 | for (int j = 0; j < i; ++j) { 13 | p[j][i] = i - j < 2 || (s[j] == s[i] && p[j+1][i-1]); 14 | if (p[j][i]) { 15 | if (i - j + 1 > max_len) { 16 | max_len = i - j + 1; 17 | max_start = j; 18 | } 19 | } 20 | } 21 | } 22 | return s.substr(max_start, max_len); 23 | 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /LeetCode/longest-substring-without-repeating-characters.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int lengthOfLongestSubstring(string s) { 4 | if (s.empty()) return 0; 5 | 6 | unordered_set used; 7 | int maxlen = 0; 8 | int start = 0, end = 0; 9 | while (end < s.size()) { 10 | if (used.find(s[end]) == used.end()) { 11 | used.insert(s[end]); 12 | } else { 13 | maxlen = max(maxlen, end - start); 14 | while (s[start] != s[end]) { 15 | used.erase(s[start]); 16 | ++start; 17 | } 18 | ++start; 19 | } 20 | ++ end; 21 | } 22 | return max(maxlen, end - start); 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /LeetCode/longest-valid-parentheses.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int longestValidParentheses(string s) { 4 | stack stk; 5 | int res = 0, last = -1; 6 | for (int i = 0; i < s.size(); ++i) { 7 | if(s[i] == '(') { 8 | stk.push(i); 9 | } else { 10 | if(stk.empty()) { 11 | last = i; 12 | } else { 13 | stk.pop(); 14 | res = max(res, stk.empty() ? i - last : i - stk.top()); 15 | } 16 | } 17 | } 18 | return res; 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /LeetCode/lru-cache.cpp: -------------------------------------------------------------------------------- 1 | class LRUCache{ 2 | private: 3 | struct CacheNode { 4 | int key; 5 | int value; 6 | CacheNode(int k, int v): key(k), value(v) {} 7 | }; 8 | 9 | int m_capacity; 10 | unordered_map::iterator> m_cmap; 11 | list m_clist; 12 | 13 | public: 14 | LRUCache(int capacity) { 15 | m_capacity = capacity; 16 | } 17 | 18 | int get(int key) { 19 | if (m_cmap.find(key) == m_cmap.end()) { 20 | return -1; 21 | } else { 22 | m_clist.splice(m_clist.begin(), m_clist, m_cmap[key]); 23 | m_cmap[key] = m_clist.begin(); 24 | return m_cmap[key]->value; 25 | } 26 | } 27 | 28 | void set(int key, int value) { 29 | if (m_cmap.find(key) == m_cmap.end()) { 30 | if (m_clist.size() == m_capacity) { 31 | m_cmap.erase(m_clist.back().key); 32 | m_clist.pop_back(); 33 | } 34 | m_clist.push_front(CacheNode(key, value)); 35 | m_cmap[key] = m_clist.begin(); 36 | } else { 37 | m_cmap[key]->value = value; 38 | m_clist.splice(m_clist.begin(), m_clist, m_cmap[key]); 39 | m_cmap[key] = m_clist.begin(); 40 | } 41 | 42 | } 43 | }; -------------------------------------------------------------------------------- /LeetCode/max-points-on-a-line.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a point. 3 | * struct Point { 4 | * int x; 5 | * int y; 6 | * Point() : x(0), y(0) {} 7 | * Point(int a, int b) : x(a), y(b) {} 8 | * }; 9 | */ 10 | class Solution { 11 | public: 12 | int maxPoints(vector &points) { 13 | int res = 0; 14 | if (points.size() <= 2) return points.size(); 15 | 16 | unordered_map slope; 17 | for (int i = 0; i < points.size(); ++i) { 18 | // start from point[i] 19 | slope.clear(); 20 | int sameone = 0; 21 | int vertical = 0; 22 | int point_max = 1; 23 | for (int j = i+1; j < points.size(); ++j) { 24 | if (points[j].x == points[i].x && points[j].y == points[i].y) { 25 | sameone += 1; 26 | } else if (points[j].x == points[i].x) { 27 | vertical = vertical == 0 ? 2 : vertical + 1; 28 | } else { 29 | double k = 1.0 * (points[j].y - points[i].y) / (points[j].x - points[i].x); 30 | if (slope.find(k) != slope.end()) slope[k] += 1; 31 | else slope[k] = 2; 32 | point_max = max(point_max, slope[k]); 33 | } 34 | } 35 | res = max(res, point_max + sameone); 36 | res = max(res, vertical + sameone); 37 | } 38 | return res; 39 | } 40 | }; -------------------------------------------------------------------------------- /LeetCode/maximal-rectangle.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maximalRectangle(vector > &matrix) { 4 | int res = 0; 5 | if(matrix.empty()) return 0; 6 | int row = matrix.size(); 7 | int col = matrix[0].size(); 8 | vector H(col, 0), R(col, col), L(col, 0); 9 | 10 | for (int i = 0; i < row; ++i) { 11 | int left = 0, right = col; 12 | for (int j = 0; j < col; ++j) { 13 | if (matrix[i][j] == '1') { 14 | L[j] = max(L[j], left); 15 | H[j] += 1; 16 | } else { 17 | H[j] = L[j] = 0; 18 | R[j] = col; 19 | left = j + 1; 20 | } 21 | } 22 | for (int j = col-1; j >= 0; --j) { 23 | if (matrix[i][j] == '1') { 24 | R[j] = min(R[j], right); 25 | // rectangle with (i,j) 26 | res = max(res, H[j]*(R[j]-L[j])); 27 | } else { 28 | right = j; 29 | } 30 | } 31 | } 32 | return res; 33 | } 34 | }; -------------------------------------------------------------------------------- /LeetCode/maximum-depth-of-binary-tree.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maxDepth(TreeNode *root) { 4 | if (root == nullptr) return 0; 5 | return 1 + max(maxDepth(root->left), maxDepth(root->right)); 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /LeetCode/maximum-subarray.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maxSubArray(int A[], int n) { 4 | int maxsum = INT_MIN, cursum = 0; 5 | for (int i = 0; i < n; ++i) { 6 | cursum += A[i]; 7 | maxsum = max(maxsum, cursum); 8 | if (cursum < 0) cursum = 0; 9 | } 10 | return maxsum; 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /LeetCode/median-of-two-sorted-arrays.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | double findMedianSortedArrays(int A[], int m, int B[], int n) { 4 | int len = m+n; 5 | if (len % 2 == 0) return (findK(A, m, B, n, len/2) + findK(A, m, B, n, len/2+1)) / 2.0; 6 | else return findK(A, m, B, n, len/2 + 1); 7 | } 8 | 9 | int findK(int A[], int m, int B[], int n, int k) { 10 | if (m > n) return findK(B, n, A, m, k); 11 | if (m == 0) return B[k-1]; 12 | if (k == 1) return min(A[0], B[0]); 13 | 14 | int a = min(k/2, m), b=k-a; 15 | if (A[a-1] < B[b-1]) return findK(A+a, m-a, B, n, k-a); 16 | else if (A[a-1] > B[b-1]) return findK(A, m, B+b, n-b, k-b); 17 | else return A[a-1]; 18 | } 19 | 20 | 21 | // solution 1, like merge sort 22 | double findMedianSortedArraysMerge(int A[], int m, int B[], int n) { 23 | int mi = 0, ni = 0, counter = 0; 24 | int first, second, cur; 25 | while (mi < m || ni < n) { 26 | int mval = mi < m ? A[mi] : INT_MAX; 27 | int nval = ni < n ? B[ni] : INT_MAX; 28 | if (mval < nval) { 29 | ++mi; 30 | cur = mval; 31 | } else { 32 | ++ni; 33 | cur = nval; 34 | } 35 | if (counter == (m + n) / 2) first = cur; 36 | if (counter == (m + n) / 2 - 1) second = cur; 37 | ++counter; 38 | } 39 | 40 | if ((m + n) % 2 == 0) return (first + second) / 2.0; 41 | else return first; 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /LeetCode/merge-intervals.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for an interval. 3 | * struct Interval { 4 | * int start; 5 | * int end; 6 | * Interval() : start(0), end(0) {} 7 | * Interval(int s, int e) : start(s), end(e) {} 8 | * }; 9 | */ 10 | class Solution { 11 | public: 12 | vector merge(vector &intervals) { 13 | vector res; 14 | if (intervals.empty()) return res; 15 | sort(intervals.begin(), intervals.end(), [&](Interval a, Interval b) { return a.start < b.start;}); 16 | res.push_back(intervals[0]); 17 | for (int i = 1; i < intervals.size(); ++i) { 18 | if(intervals[i].start > res.back().end) { 19 | res.push_back(intervals[i]); 20 | } else { 21 | res.back().end = max(res.back().end, intervals[i].end); 22 | } 23 | } 24 | return res; 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /LeetCode/merge-k-sorted-lists.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | /*ListNode *mergeKLists(vector &lists) { 4 | if (lists.size() == 0) return nullptr; 5 | ListNode *p = lists[0]; 6 | for (int i = 1; i < lists.size(); i++) p = mergeTwoList(p, lists[i]); 7 | return p; 8 | } 9 | 10 | ListNode *mergeTwoList(ListNode *l1, ListNode *l2) { 11 | ListNode dumpy(-1); 12 | ListNode *p = &dumpy; 13 | while (l1 != nullptr || l2 != nullptr) { 14 | int val1 = l1 == nullptr ? INT_MAX : l1->val; 15 | int val2 = l2 == nullptr ? INT_MAX : l2->val; 16 | if (val1 < val2) { 17 | p->next = l1; 18 | l1 = l1->next; 19 | } else { 20 | p->next = l2; 21 | l2 = l2->next; 22 | } 23 | p = p->next; 24 | } 25 | return dumpy.next; 26 | }*/ 27 | 28 | struct cmp { 29 | bool operator()(const ListNode* a, const ListNode* b) { 30 | return a->val > b->val; 31 | } 32 | }; 33 | 34 | ListNode *mergeKLists(vector &lists) { 35 | priority_queue, cmp> minheap; 36 | for (int i = 0; i < lists.size(); i++) { 37 | if (lists[i] != nullptr) minheap.push(lists[i]); 38 | } 39 | ListNode dummy(-1); 40 | ListNode *p = &dummy; 41 | while (!minheap.empty()) { 42 | ListNode* cur = minheap.top(); 43 | p->next = cur; 44 | p = p->next; 45 | minheap.pop(); 46 | if (cur->next) minheap.push(cur->next); 47 | } 48 | return dummy.next; 49 | } 50 | }; 51 | -------------------------------------------------------------------------------- /LeetCode/merge-sorted-array.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void merge(int A[], int m, int B[], int n) { 4 | int i = m-1; 5 | int j = n-1; 6 | int x = m + n - 1; 7 | while (x >= 0) { 8 | if (j < 0 || i < 0) break; 9 | if (A[i] > B[j]) A[x--] = A[i--]; 10 | else A[x--] = B[j--]; 11 | } 12 | while (j >= 0) A[x--] = B[j--]; 13 | } 14 | }; -------------------------------------------------------------------------------- /LeetCode/merge-two-sorted-lists.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) { 4 | if (l1 == nullptr) return l2; 5 | if (l2 == nullptr) return l1; 6 | ListNode *head; 7 | if (l1->val <= l2->val) { 8 | head = l1; 9 | head->next = mergeTwoLists(l1->next, l2); 10 | } else { 11 | head = l2; 12 | head->next = mergeTwoLists(l1, l2->next); 13 | } 14 | return head; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /LeetCode/minimum-depth-of-binary-tree-bfs.cpp: -------------------------------------------------------------------------------- 1 | // Time O(n), Space O(n) 2 | class Solution { 3 | public: 4 | int minDepth(TreeNode *root) { 5 | if (root == nullptr) return 0; 6 | queue current, next; 7 | int len = 0; 8 | current.push(root); 9 | while (!current.empty()) { 10 | len += 1; 11 | while (!current.empty()) { 12 | TreeNode *p = current.front(); 13 | current.pop(); 14 | if (p->left == nullptr && p->right == nullptr) return len; 15 | if (p->left) next.push(p->left); 16 | if (p->right) next.push(p->right); 17 | } 18 | current.swap(next); 19 | } 20 | return len; 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /LeetCode/minimum-depth-of-binary-tree-dfs.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int minDepth(TreeNode *root) { 4 | return depth(root, false); 5 | } 6 | 7 | int depth(TreeNode *root, bool has_bro) { 8 | if (root == nullptr) return has_bro ? INT_MAX : 0; 9 | return 1 + min(depth(root->left, root->right != nullptr), depth(root->right, root->left != nullptr)); 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /LeetCode/minimum-path-sum.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int minPathSum(vector > &grid) { 4 | if (grid.empty()) return 0; 5 | int m = grid.size(); 6 | int n = grid[0].size(); 7 | vector > E(m, vector(n, 0)); 8 | for (int i = 1; i < m; ++i) E[i][0] = E[i-1][0] + grid[i-1][0]; 9 | for (int j = 1; j < n; ++j) E[0][j] = E[0][j-1] + grid[0][j-1]; 10 | for (int i = 1; i < m; ++i) { 11 | for(int j = 1; j < n; ++j) { 12 | E[i][j] = min(E[i-1][j] + grid[i-1][j], E[i][j-1] + grid[i][j-1]); 13 | } 14 | } 15 | return E[m-1][n-1] + grid[m-1][n-1]; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /LeetCode/minimum-window-substring.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | string minWindow(string S, string T) { 4 | if (T.empty() || S.size() < T.size()) return ""; 5 | unordered_map appeared, expected; 6 | for (auto c: T) { 7 | expected[c] += 1; 8 | appeared[c] = 0; 9 | } 10 | int start = 0, minstart = 0, minlen = INT_MAX, total = 0; 11 | for (int i = 0; i < S.size(); ++i) { 12 | if (expected.find(S[i]) != expected.end()) { 13 | if (appeared[S[i]] < expected[S[i]]) total += 1; 14 | appeared[S[i]] += 1; 15 | } 16 | if (total == T.size()) { 17 | // shorten, not found, more than expected 18 | while (expected.find(S[start]) == expected.end() || appeared[S[start]] > expected[S[start]]) { 19 | appeared[S[start]] -= 1; 20 | start += 1; 21 | } 22 | if (i - start + 1 < minlen) { 23 | minlen = i - start + 1; 24 | minstart = start; 25 | } 26 | } 27 | } 28 | return minlen == INT_MAX ? "" : S.substr(minstart, minlen); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /LeetCode/multiply-strings.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | string multiply(string num1, string num2) { 4 | int len1 = num1.size(); 5 | int len2 = num2.size(); 6 | vector v1, v2; 7 | for(int i = len1-1; i >= 0; --i) v1.push_back(num1[i]-'0'); 8 | for(int i = len2-1; i >= 0; --i) v2.push_back(num2[i]-'0'); 9 | 10 | 11 | vector ans(len1+len2+1, 0); 12 | for (int i = 0; i < len2; ++i) { 13 | int c = 0; 14 | for (int j = 0; j < len1; ++j) { 15 | ans[i+j] += v2[i] * v1[j] + c; 16 | c = ans[i+j] / 10; 17 | ans[i+j] = ans[i+j] % 10; 18 | } 19 | if (c > 0) ans[i+len1] += c; 20 | } 21 | 22 | ostringstream res; 23 | bool start = true; 24 | for(int i=ans.size()-1; i>=0; --i) { 25 | if (ans[i] != 0) start = false; 26 | if (!start) res << ans[i]; 27 | } 28 | if(start) res << 0; 29 | return res.str(); 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /LeetCode/n-queens-ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int totalNQueens(int n) { 4 | int res = 0;; 5 | if (n == 0) return res; 6 | vector col_visit(n, false), d1_visit(2*n+1, false), d2_visit(2*n+1, false); 7 | solve(n, 0, col_visit, d1_visit, d2_visit, res); 8 | return res; 9 | } 10 | 11 | void solve(int n, int row, vector &col_visit, vector &d1_visit, vector &d2_visit, int &res) { 12 | if(row == n) { 13 | res += 1; 14 | return; 15 | } 16 | for (int col = 0; col < n; col++) { 17 | if (!col_visit[col] && !d1_visit[row+col] && !d2_visit[n+row-col]) { 18 | col_visit[col] = d1_visit[row+col] = d2_visit[n+row-col] = true; 19 | solve(n, row+1, col_visit, d1_visit, d2_visit, res); 20 | col_visit[col] = d1_visit[row+col] = d2_visit[n+row-col] = false; 21 | } 22 | } 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /LeetCode/n-queens.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector > solveNQueens(int n) { 4 | vector > res; 5 | if (n == 0) return res; 6 | vector path; 7 | vector col_visit(n, false), d1_visit(2*n+1, false), d2_visit(2*n+1, false); 8 | 9 | solve(n, 0, col_visit, d1_visit, d2_visit, path, res); 10 | return res; 11 | } 12 | 13 | void solve(int n, int row, vector &col_visit, vector &d1_visit, vector &d2_visit, 14 | vector &path, vector > &res) { 15 | if(row == n) { 16 | vector spath; 17 | for (auto x: path) { 18 | string temp(n, '.'); 19 | temp[x] = 'Q'; 20 | spath.push_back(temp); 21 | } 22 | res.push_back(spath); 23 | return; 24 | } 25 | for (int col = 0; col < n; ++col) { 26 | if (!col_visit[col] && !d1_visit[row+col] && !d2_visit[n+row-col]) { 27 | col_visit[col] = d1_visit[row+col] = d2_visit[n+row-col] = true; 28 | path.push_back(col); 29 | solve(n, row+1, col_visit, d1_visit, d2_visit, path, res); 30 | path.pop_back(); 31 | col_visit[col] = d1_visit[row+col] = d2_visit[n+row-col] = false; 32 | } 33 | } 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /LeetCode/next-permutation.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void nextPermutation(vector &num) { 4 | next_permutation(num.begin(), num.end()); 5 | } 6 | 7 | template 8 | bool next_permutation(BidIt begin, BidIt end) { 9 | auto rbegin = reverse_iterator(end); 10 | auto rend = reverse_iterator(begin); 11 | auto pivot = next(rbegin); 12 | while (pivot != rend && *pivot >= 13 | *prev(pivot)) ++pivot; 14 | if (pivot == rend) { 15 | reverse(rbegin, 16 | rend); 17 | return 18 | false; 19 | } 20 | else { 21 | auto p = rbegin; 22 | while 23 | (*p 24 | <= 25 | *pivot) 26 | ++p; 27 | swap(*p, 28 | *pivot); 29 | reverse(rbegin, 30 | pivot); 31 | return 32 | true; 33 | } 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /LeetCode/palindrome-number.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool isPalindrome(int x) { 4 | if (x < 0) return false; 5 | int d = 1; 6 | // CAUSION: avoid overflow 7 | while (x / d >= 10) d *= 10; 8 | 9 | while (x != 0) { 10 | int left = x / d; 11 | int right = x % 10; 12 | if (left != right) return false; 13 | x = (x % d) / 10; 14 | d /= 100; 15 | } 16 | return true; 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /LeetCode/palindrome-partitioning-ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int minCut(string s) { 4 | int n =s.size(); 5 | if(s.size() == 0 || s.size() == 1) return 0; 6 | vector > p(n, vector(n, false)); 7 | for (int i = n - 1; i >= 0; --i) { 8 | for (int j = i; j < n; ++j) { 9 | p[i][j] = (j-i < 2 || p[i+1][j-1]) && s[i] == s[j]; 10 | } 11 | } 12 | 13 | vector cuts = vector(n, n); 14 | cuts[0] = 0; 15 | for (int i = 1; i < n; i++) { 16 | for (int j = 0; j <= i; j++) { 17 | if (p[j][i]) { 18 | if (j == 0) cuts[i] = 0; // self parlindrome 19 | else if (cuts[j-1] + 1 < cuts[i]) { 20 | cuts[i] = cuts[j-1] + 1; 21 | } 22 | } 23 | } 24 | 25 | } 26 | return cuts[n-1]; 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /LeetCode/palindrome-partitioning.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector> partition(string s) { 4 | vector > res; 5 | if (s.empty()) return res; 6 | int n = s.size(); 7 | vector path; 8 | 9 | vector > p(n, vector(n, false)); 10 | for (int i = n - 1; i >= 0; --i) { 11 | for (int j = i; j < n; ++j) { 12 | p[i][j] = (j-i < 2 || p[i+1][j-1]) && s[i] == s[j]; 13 | } 14 | } 15 | 16 | dfs(s, 0, p, path, res); 17 | return res; 18 | } 19 | 20 | void dfs(const string &s, int start, vector > &p, vector &path, 21 | vector > &res) { 22 | if (start == s.size()) { 23 | res.push_back(path); 24 | return; 25 | } 26 | for (int i = start; i < s.size(); ++i) { 27 | if (p[start][i]) { 28 | string word = s.substr(start, i - start + 1); 29 | path.push_back(word); 30 | dfs(s, i + 1, p, path, res); 31 | path.pop_back(); 32 | } 33 | } 34 | } 35 | 36 | // deprecated, too slow 37 | bool ispalindrome(const string &word) { 38 | int start = 0, end = word.size() - 1; 39 | while (start < end) { 40 | if (word[start] != word[end]) return false; 41 | start++; 42 | end--; 43 | } 44 | return true; 45 | } 46 | 47 | }; 48 | -------------------------------------------------------------------------------- /LeetCode/partition-list.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for singly-linked list. 3 | * struct ListNode { 4 | * int val; 5 | * ListNode *next; 6 | * ListNode(int x) : val(x), next(NULL) {} 7 | * }; 8 | */ 9 | 10 | class Solution { 11 | public: 12 | ListNode *partition(ListNode *head, int x) { 13 | if (head == nullptr || head->next == nullptr) return head; 14 | ListNode dumpy1(-1), dumpy2(-1); 15 | ListNode *l1 = &dumpy1, *l2 = &dumpy2; 16 | for (ListNode *p = head; p != nullptr; p = p->next) { 17 | if (p->val < x) { 18 | l1->next = p; 19 | l1 = l1->next; 20 | } else { 21 | l2->next = p; 22 | l2 = l2->next; 23 | } 24 | } 25 | l1->next = dumpy2.next; 26 | l2->next = nullptr; 27 | return dumpy1.next; 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /LeetCode/pascals-triangle-ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector getRow(int rowIndex) { 4 | vector f = {1}; 5 | for (int i = 1; i <= rowIndex; ++i) { 6 | for (int j = i - 1; j > 0; --j) { 7 | f[j] = f[j] + f[j-1]; 8 | } 9 | f.push_back(1); // f[i] 10 | } 11 | return f; 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /LeetCode/pascals-triangle.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector > generate(int numRows) { 4 | vector > res; 5 | if (numRows == 0) return res; 6 | res.push_back({1}); 7 | vector f = {1}; 8 | for (int i = 1; i < numRows; ++i) { 9 | for (int j = i - 1; j > 0; --j) { 10 | f[j] = f[j] + f[j-1]; 11 | } 12 | f.push_back(1); // f[i] 13 | res.push_back(f); 14 | } 15 | return res; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /LeetCode/path-sum-ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector > pathSum(TreeNode *root, int sum) { 4 | vector > res; 5 | if (root == nullptr) return res; 6 | vector path; 7 | dfs(root, sum, res, path); 8 | return res; 9 | } 10 | 11 | void dfs(TreeNode *root, int sum, vector > &res, vector &path) { 12 | if (root == nullptr) { 13 | if (sum == 0) res.push_back(path); 14 | } else { 15 | path.push_back(root->val); 16 | if (root->left == nullptr && root->right == nullptr) { 17 | if (sum == root->val) res.push_back(path); 18 | } else { 19 | if (root->left) dfs(root->left, sum - root->val, res, path); 20 | if (root->right) dfs(root->right, sum - root->val, res, path); 21 | } 22 | path.pop_back(); 23 | } 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /LeetCode/path-sum.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool hasPathSum(TreeNode *root, int sum) { 4 | if(root == nullptr) return false; 5 | return hasSum(root, sum); 6 | } 7 | 8 | bool hasSum(TreeNode *root, int sum) { 9 | if(root == nullptr) return sum == 0; 10 | if(root->left == nullptr && root->right == nullptr) return sum == root->val; 11 | if(root->left != nullptr && hasSum(root->left, sum - root->val) ) return true; 12 | if(root->right != nullptr && hasSum(root->right, sum - root->val) ) return true; 13 | return false; 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /LeetCode/permutation-sequence.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int fac(int n) { 4 | int res = 1; 5 | for (int i = 2; i <= n; ++i) res *= i; 6 | return res; 7 | } 8 | 9 | string kpermutation(string s, int k) { 10 | string res; 11 | int n = s.size(); 12 | int base = fac(n-1); 13 | k -= 1; // start from 0 14 | 15 | for (int i = n - 1; i > 0; --i) { 16 | auto a = next(s.begin(), k/base); 17 | res.push_back(*a); 18 | s.erase(a); 19 | k %= base; 20 | base /= i; 21 | } 22 | res.push_back(s[0]); 23 | return res; 24 | } 25 | 26 | string getPermutation(int n, int k) { 27 | string s(n, '0'); 28 | for (int i = 0; i < n; ++i) s[i] += (i+1); 29 | return kpermutation(s, k); 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /LeetCode/permutations-ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector > permuteUnique(vector &num) { 4 | vector > res; 5 | if(num.empty()) return res; 6 | sort(num.begin(), num.end()); 7 | do { 8 | res.push_back(num); 9 | } while(std::next_permutation(num.begin(), num.end())); 10 | return res; 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /LeetCode/permutations.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector > permute(vector &num) { 4 | vector > res; 5 | if(num.empty()) return res; 6 | sort(num.begin(), num.end()); 7 | do { 8 | res.push_back(num); 9 | } while(next_permutation(num.begin(), num.end())); 10 | return res; 11 | } 12 | 13 | template 14 | bool next_permutation(BidIt begin, BidIt end) { 15 | auto rbegin = reverse_iterator(end); 16 | auto rend = reverse_iterator(begin); 17 | auto pivot = next(rbegin); 18 | while (pivot != rend && *pivot >= *prev(pivot)) ++pivot; 19 | if (pivot == rend) { 20 | reverse(rbegin, rend); 21 | return false; 22 | } else { 23 | auto p = rbegin; 24 | while (*p <= *pivot) ++p; 25 | swap(*p, *pivot); 26 | reverse(rbegin, pivot); 27 | return true; 28 | } 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /LeetCode/plus-one.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector plusOne(vector &digits) { 4 | int len = digits.size(); 5 | vector output(len + 1, 0); 6 | int c = 1; 7 | for(int i = len-1; i >= 0; --i) { 8 | int sum = digits[i] + c; 9 | output[i+1] = sum % 10; 10 | c = sum / 10; 11 | } 12 | if(c == 1) output[0] = 1; 13 | else output.erase(output.begin()); 14 | return output; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /LeetCode/populating-next-right-pointers-in-each-node-ii.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for binary tree with next pointer. 3 | * struct TreeLinkNode { 4 | * int val; 5 | * TreeLinkNode *left, *right, *next; 6 | * TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {} 7 | * }; 8 | */ 9 | class Solution { 10 | public: 11 | void connect(TreeLinkNode *root) { 12 | while(root != nullptr) { 13 | TreeLinkNode *next = nullptr, *pre=nullptr; 14 | while(root != nullptr) { 15 | if(next == nullptr) next = root->left == nullptr ? root->right : root->left; 16 | if(root->left != nullptr) { 17 | if(pre != nullptr) pre->next = root->left; 18 | pre = root->left; 19 | } 20 | if(root->right != nullptr) { 21 | if(pre != nullptr) pre->next = root->right; 22 | pre = root->right;; 23 | } 24 | root = root->next; 25 | } 26 | root = next; 27 | } 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /LeetCode/populating-next-right-pointers-in-each-node.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for binary tree with next pointer. 3 | * struct TreeLinkNode { 4 | * int val; 5 | * TreeLinkNode *left, *right, *next; 6 | * TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {} 7 | * }; 8 | */ 9 | class Solution { 10 | public: 11 | void connect(TreeLinkNode *root) { 12 | while(root != nullptr) { 13 | TreeLinkNode *next = nullptr, *pre=nullptr; 14 | while(root != nullptr) { 15 | if(next == nullptr) next = root->left == nullptr ? root->right : root->left; 16 | if(root->left != nullptr) { 17 | if(pre != nullptr) pre->next = root->left; 18 | pre = root->left; 19 | } 20 | if(root->right != nullptr) { 21 | if(pre != nullptr) pre->next = root->right; 22 | pre = root->right;; 23 | } 24 | root = root->next; 25 | } 26 | root = next; 27 | } 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /LeetCode/powx-n.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | double pow(double x, int n) { 4 | if (x == 1) return 1; 5 | if (x == -1) return (n % 2 == 0) ? 1 : -1; 6 | if(n == 0) return 1.0; 7 | 8 | if(n < 0) return 1.0 / pow(x, -n); 9 | double part = pow(x, n/2); 10 | return (n % 2 == 0) ? part*part : part*part*x; 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /LeetCode/recover-binary-search-tree.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | TreeNode *first_node, *second_node, *pre_node; 4 | void recoverTree(TreeNode *root) { 5 | first_node = nullptr; 6 | second_node = nullptr; 7 | pre_node = nullptr; 8 | inorder(root); 9 | swap(first_node->val, second_node->val); 10 | } 11 | 12 | void inorder(TreeNode *root) { 13 | if(root == nullptr) return; 14 | inorder(root->left); 15 | if (pre_node != nullptr && root->val < pre_node->val) { 16 | if(first_node == nullptr) first_node = pre_node; 17 | second_node = root; 18 | } 19 | pre_node = root; 20 | inorder(root->right); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /LeetCode/regular-expression-matching.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool isMatch(const char *s, const char *p) { 4 | if (*p == '\0') return *s == '\0'; 5 | 6 | if (*(p+1) != '*') { 7 | if(*p == *s || (*p == '.' && *s != '\0')) return isMatch(s+1, p+1); 8 | else return false; 9 | } else { 10 | while (*p == *s || (*p == '.' && *s != '\0')) { 11 | if (isMatch(s, p+2)) return true; 12 | s++; 13 | } 14 | return isMatch(s, p+2); 15 | } 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /LeetCode/remove-duplicates-from-sorted-array-ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int removeDuplicates(int A[], int n) { 4 | if (n <= 2) return n; 5 | int len = 1; 6 | int pre = A[0]; 7 | int pre_cnt = 1; 8 | for (int i = 1; i < n; ++i) { 9 | if (A[i] != pre || pre_cnt < 2) { 10 | if (pre == A[i]) pre_cnt += 1; 11 | else pre_cnt = 1; 12 | 13 | pre = A[i]; 14 | A[len++] = A[i]; 15 | } 16 | } 17 | return len; 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /LeetCode/remove-duplicates-from-sorted-array.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int removeDuplicates(int A[], int n) { 4 | if(n <= 1) return n; 5 | int len = 1; 6 | int pre = A[0]; 7 | for (int i = 1; i < n; ++i) { 8 | if (A[i] != pre) { 9 | pre = A[i]; 10 | A[len++] = A[i]; 11 | } 12 | } 13 | return len; 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /LeetCode/remove-duplicates-from-sorted-list-ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | ListNode *deleteDuplicates(ListNode *head) { 4 | ListNode dumpy(-1); 5 | ListNode *newp = &dumpy; 6 | ListNode *p = head; 7 | while (p) { 8 | bool flag = true; 9 | ListNode *next = p->next; 10 | while (next && next->val == p->val) { 11 | flag = false; 12 | next = next->next; 13 | } 14 | // no duplicate 15 | if (flag) { 16 | newp->next = p; 17 | newp = p; 18 | } 19 | p = next; 20 | } 21 | // DONOT Forget the last element 22 | newp->next = nullptr; 23 | return dumpy.next; 24 | } 25 | }; -------------------------------------------------------------------------------- /LeetCode/remove-duplicates-from-sorted-list.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | ListNode *deleteDuplicates(ListNode *head) { 4 | if (head == nullptr) return head; 5 | ListNode *pre = head; 6 | for (ListNode *p = head->next; p; p = p->next) { 7 | if (p->val == pre->val) { 8 | pre->next = p->next; 9 | } else pre = p; 10 | } 11 | return head; 12 | } 13 | }; -------------------------------------------------------------------------------- /LeetCode/remove-element.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int removeElement(int A[], int n, int elem) { 4 | int j = 0; 5 | for (int i = 0; i < n; ++i) { 6 | if (A[i] == elem) continue; 7 | A[j++] = A[i]; 8 | } 9 | return j; 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /LeetCode/remove-nth-node-from-end-of-list.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | ListNode *removeNthFromEnd(ListNode *head, int n) { 4 | if (head == nullptr || n == 0) return head; 5 | ListNode dumpy(-1); 6 | dumpy.next = head; 7 | ListNode *slow = &dumpy, *fast = &dumpy; 8 | for (int i = 0; i < n; ++i) { 9 | fast = fast->next; 10 | } 11 | while(fast->next != nullptr) { 12 | fast = fast->next; 13 | slow = slow->next; 14 | } 15 | 16 | ListNode *tmp = slow->next; 17 | slow->next = slow->next->next; 18 | delete tmp; 19 | return dumpy.next; 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /LeetCode/reorder-list.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for singly-linked list. 3 | * struct ListNode { 4 | * int val; 5 | * ListNode *next; 6 | * ListNode(int x) : val(x), next(NULL) {} 7 | * }; 8 | */ 9 | class Solution { 10 | public: 11 | ListNode* reverse(ListNode *head) { 12 | if (head == nullptr || head->next == nullptr) return head; 13 | ListNode *head2 = head, *cur = head, *pre = nullptr; 14 | while (cur != nullptr) { 15 | ListNode *next = cur->next; 16 | cur->next = pre; 17 | head2 = cur; 18 | pre = cur; 19 | cur = next; 20 | } 21 | return head2; 22 | } 23 | 24 | void reorderList(ListNode *head) { 25 | if (head == nullptr || head->next == nullptr) return; 26 | ListNode *fast=head, *slow=head; 27 | while (fast != nullptr && fast->next != nullptr && fast->next->next != nullptr) { 28 | fast = fast->next->next; 29 | slow = slow->next; 30 | } 31 | ListNode *head2 = reverse(slow->next); 32 | slow->next = nullptr; 33 | 34 | // merge two list 35 | ListNode dumpy(-1); 36 | ListNode *p = &dumpy; 37 | while (head != nullptr && head2 != nullptr) { 38 | p->next = head; 39 | p = p->next; 40 | head = head->next; 41 | p->next = head2; 42 | p = p->next; 43 | head2 = head2->next; 44 | } 45 | if (head != nullptr) p->next = head; 46 | head = dumpy.next; 47 | } 48 | }; -------------------------------------------------------------------------------- /LeetCode/restore-ip-addresses.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector restoreIpAddresses(string s) { 4 | vector res; 5 | string path; 6 | gen(res, path, s, 0, 0); 7 | return res; 8 | } 9 | 10 | void gen(vector &res, string path, string &s, int start, int level) { 11 | if (level == 4 && start == s.size()) { 12 | path.erase(path.end() - 1); 13 | res.push_back(path); 14 | return; 15 | } 16 | if (s.size() - start > (4-level)*3) return; 17 | if (s.size() - start < (4-level)) return; 18 | for (int len = 1; len <= 3 && start + len <= s.size(); ++len) { 19 | string seg = s.substr(start, len); 20 | if((seg.size() >= 2 && seg[0] == '0') || atoi(seg.c_str()) > 255) continue; 21 | gen(res, path + seg + ".", s, start + len, level + 1); 22 | } 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /LeetCode/reverse-integer.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int reverse(int x) { 4 | if (x < 0) return -reverse(-x); 5 | 6 | int res = 0; 7 | // may have overflow problem, e.g. x = 1000000003 8 | while (x != 0) { 9 | res = res * 10 + x % 10; 10 | x = x / 10; 11 | } 12 | return res; 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /LeetCode/reverse-linked-list-ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | ListNode *reverseBetween(ListNode *head, int m, int n) { 4 | if (m == n || head == nullptr) return head; 5 | ListNode dumpy(-1); 6 | dumpy.next = head; 7 | ListNode *pre_head = &dumpy; 8 | for (int i = 0; i < m - 1; ++i) pre_head = pre_head->next; 9 | ListNode *p = pre_head->next; 10 | 11 | ListNode *next = p->next; 12 | for (int i = m; i < n; ++i) { 13 | p->next = next->next; 14 | next->next = pre_head->next; 15 | pre_head->next = next; 16 | next = p->next; 17 | } 18 | return dumpy.next; 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /LeetCode/reverse-nodes-in-k-group.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | ListNode *reverseKGroup(ListNode *head, int k) { 4 | if (head == nullptr || head->next == nullptr) return head; 5 | int n = 0; 6 | for (ListNode *p=head; p; p = p->next) n++; 7 | if (k > n || k == 1) return head; 8 | 9 | ListNode dumpy(-1); 10 | ListNode *pre = nullptr, *cur = nullptr, *next = head; // for reverse 11 | ListNode *pre_last = &dumpy, *cur_last = nullptr; // group link 12 | 13 | for (int g = 0; g < n/k; g++) { 14 | // reverse linked list in this group 15 | cur_last = next; 16 | for (int i = 0; i < k; i++) { 17 | cur = next; 18 | next = cur->next; 19 | cur->next = pre; 20 | pre = cur; 21 | } 22 | pre_last->next = cur; 23 | pre_last = cur_last; 24 | } 25 | // link remaining nodes 26 | pre_last->next = next; 27 | return dumpy.next; 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /LeetCode/reverse-words-in-a-string.cpp: -------------------------------------------------------------------------------- 1 | class Solution { public: // O(n) time void reverseWords(string &s) { vector words; string cur = ""; for (int i = 0; i < s.size(); ++i) { if (s[i] != ' ') { cur += s[i]; } else { // a new word is generated if (cur.size() != 0) words.push_back(cur); cur = ""; } } // the last word if (cur.size() != 0) words.push_back(cur); s = ""; for (int i = words.size() - 1; i >= 0; --i) { s += words[i]; if(i != 0) s += " "; } } }; -------------------------------------------------------------------------------- /LeetCode/roman-to-integer.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int romanToInt(string s) { 4 | // I(1) V(5) X(10) L(50) C(100) D(500) M(1000) 5 | const int radix[] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}; 6 | const string symbols[] = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"}; 7 | 8 | map du_dict; 9 | map si_dict; 10 | for (int i = 0; i < 13; ++i) { 11 | if (symbols[i].size() == 2) du_dict[symbols[i]] = radix[i]; 12 | else si_dict[symbols[i]] = radix[i]; 13 | } 14 | 15 | int res = 0; 16 | for (int i = 0; i < s.size(); ++i) { 17 | if (i != s.size() - 1 && du_dict.find(s.substr(i, 2)) != du_dict.end()) { 18 | res += du_dict[s.substr(i,2)]; 19 | ++i; 20 | } else { 21 | res += si_dict[s.substr(i,1)]; 22 | } 23 | } 24 | return res; 25 | 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /LeetCode/rotate-image.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void rotate(vector > &matrix) { 4 | if (matrix.empty()) return; 5 | int m = matrix.size(); 6 | for (int i = 0; i < m-1; i++) { 7 | for (int j = 0; j < m-1-i; j++) { 8 | swap(matrix[i][j], matrix[m-1-j][m-1-i]); 9 | } 10 | } 11 | for (int i = 0; i < m/2; i++) { 12 | for (int j = 0; j < m; j++) { 13 | swap(matrix[i][j], matrix[m-1-i][j]); 14 | } 15 | } 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /LeetCode/rotate-list.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | ListNode *rotateRight(ListNode *head, int k) { 4 | if (head == nullptr || k == 0) return head; 5 | 6 | int n = 1; 7 | ListNode *p = head; 8 | while (p->next) { 9 | n += 1; 10 | p = p->next; 11 | } 12 | k = n - k % n; 13 | // form a circle 14 | p->next = head; 15 | 16 | for (int i = 0; i < k; ++i) { 17 | p = p->next; 18 | } 19 | head = p->next; 20 | // cut the circle 21 | p->next = nullptr; 22 | return head; 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /LeetCode/same-tree.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool isSameTree(TreeNode *p, TreeNode *q) { 4 | if (p == nullptr) return q == nullptr; 5 | if (q == nullptr) return p == nullptr; 6 | if (p->val != q->val) return false; 7 | if (!isSameTree(p->left, q->left)) return false; 8 | if (!isSameTree(p->right, q->right)) return false; 9 | return true; 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /LeetCode/scramble-string.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool isScramble(string s1, string s2) { 4 | int m = s1.size(); 5 | int n = s2.size(); 6 | if (m != n) return false; 7 | if (n == 0) return true; 8 | // given the len, start from i in s1, start from j in s2 9 | bool f[n+1][n][n]; 10 | fill_n(&f[0][0][0], (n+1)*n*n, false); 11 | for (int i = 0; i < n; ++i) 12 | for (int j = 0; j < n; ++j) 13 | f[1][i][j] = s1[i] == s2[j]; 14 | 15 | for (int len = 2; len <= n; ++len) { 16 | for (int i = 0; i + len <= n; ++i) { 17 | for (int j = 0; j + len <= n; ++j) { 18 | for (int k = 1; k < len; ++k) { 19 | if (f[k][i][j] && f[len-k][i+k][j+k] 20 | || f[k][i][j+len-k] && f[len-k][i+k][j]) { 21 | f[len][i][j] = true; 22 | break; 23 | } 24 | } 25 | } 26 | } 27 | } 28 | return f[n][0][0]; 29 | } 30 | }; -------------------------------------------------------------------------------- /LeetCode/search-a-2d-matrix.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool searchMatrix(vector > &matrix, int target) { 4 | if (matrix.empty()) return false; 5 | int m = matrix.size(); 6 | int n = matrix[0].size(); 7 | int start = 0, end = m*n; 8 | while (start < end) { 9 | int mid = start + (end - start)/2; 10 | int row = mid / n; 11 | int col = mid - n*row; 12 | if (matrix[row][col] == target) return true; 13 | else if (matrix[row][col] < target) start = mid + 1; 14 | else end = mid; 15 | } 16 | return false; 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /LeetCode/search-for-a-range.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector searchRange(int A[], int n, int target) { 4 | int lower = lower_bound(A, n, target); 5 | int upper = upper_bound(A, n, target); 6 | return {lower, upper}; 7 | } 8 | 9 | int lower_bound(int A[], int n, int target) { 10 | int start = 0; 11 | int end = n; 12 | int res = -1; 13 | while (start < end) { 14 | int mid = start + (end - start) / 2; 15 | if (A[mid] == target) { 16 | res = mid; 17 | end = mid; 18 | } else if (A[mid] < target) start = mid + 1; 19 | else end = mid; 20 | } 21 | return res; 22 | } 23 | 24 | int upper_bound(int A[], int n, int target) { 25 | int start = 0; 26 | int end = n; 27 | int res = -1; 28 | while (start < end) { 29 | int mid = start + (end - start) / 2; 30 | if (A[mid] == target) { 31 | res = mid; 32 | start = mid + 1; 33 | } else if (A[mid] < target) start = mid + 1; 34 | else end = mid; 35 | } 36 | return res; 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /LeetCode/search-in-rotated-sorted-array-ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool search(int A[], int n, int target) { 4 | int start = 0; 5 | int end = n; 6 | while (start < end) { 7 | int mid = start + (end - start) / 2; 8 | if (A[mid] == target) return true; 9 | if (A[start] < A[mid]) { 10 | if(A[mid] > target && A[start] <= target) end = mid; 11 | else start = mid+1; 12 | } else if (A[start] > A[mid]){ 13 | if (A[mid] < target && A[end-1] >= target) start = mid+1; 14 | else end = mid; 15 | } else { 16 | start += 1; 17 | } 18 | } 19 | return false; 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /LeetCode/search-in-rotated-sorted-array.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int search(int A[], int n, int target) { 4 | int start = 0; 5 | int end = n; 6 | while (start < end) { 7 | int mid = start + (end - start) / 2; 8 | if (A[mid] == target) return mid; 9 | if (A[start] < A[mid]) { 10 | if (target >= A[start] && target < A[mid]) end = mid; 11 | else start = mid + 1; 12 | } else { 13 | if (target > A[mid] && target <= A[end-1]) start = mid + 1; 14 | else end = mid; 15 | } 16 | } 17 | return -1; 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /LeetCode/search-insert-position.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int searchInsert(int A[], int n, int target) { 4 | int start = 0, end = n; 5 | while (start < end) { 6 | int mid = start + (end - start) / 2; 7 | if (A[mid] == target) return mid; 8 | else if(A[mid] < target) start = mid + 1; 9 | else end = mid; 10 | } 11 | return start; 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /LeetCode/set-matrix-zeroes.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void setZeroes(vector > &matrix) { 4 | if(matrix.empty()) return; 5 | int m = matrix.size(); 6 | int n = matrix[0].size(); 7 | bool col_has_zero = false, row_has_zero = false; 8 | for (int i = 0; i < m; ++i) if (matrix[i][0] == 0) col_has_zero = true; 9 | for (int j = 0; j < n; ++j) if (matrix[0][j] == 0) row_has_zero = true; 10 | 11 | // save all zero tags to matrix boarder 12 | for (int i = 1; i < m; ++i) { 13 | for (int j = 1; j < n; ++j) { 14 | if (matrix[i][j] == 0) { 15 | matrix[i][0] = 0; 16 | matrix[0][j] = 0; 17 | } 18 | } 19 | } 20 | 21 | // set zeros according to the tags 22 | for (int i = 1; i < m; ++i) { 23 | for (int j = 1; j < n; ++j) { 24 | if (matrix[i][0] == 0 || matrix[0][j] == 0) matrix[i][j] = 0; 25 | } 26 | } 27 | // set corner cases 28 | if (col_has_zero) for(int i = 0; i < m; ++i) matrix[i][0] = 0; 29 | if (row_has_zero) for(int j = 0; j < n; ++j) matrix[0][j] = 0; 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /LeetCode/simplify-path.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | string simplifyPath(string path) { 4 | stack s; 5 | string cur; 6 | for (int i = 0; i <= path.size(); ++i) { 7 | if (i == path.size() || path[i] == '/') { 8 | if (cur.size() == 0 || cur == ".") { 9 | cur = ""; 10 | continue; 11 | } else if (cur == "..") { 12 | if(!s.empty()) s.pop(); 13 | } else { 14 | s.push(cur); 15 | } 16 | cur = ""; 17 | } else { 18 | cur += path[i]; 19 | } 20 | } 21 | if (s.empty()) return "/"; 22 | string res = ""; 23 | while (!s.empty()) { 24 | res = "/" + s.top() + res; 25 | s.pop(); 26 | } 27 | return res; 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /LeetCode/single-number-ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int singleNumber(int A[], int n) { 4 | vector count(32, 0); 5 | for (int i = 0; i < n; ++i) { 6 | for (int j = 0; j < 32; ++j) { 7 | count[j] += ((A[i]>>j) & 1); 8 | count[j] %= 3; 9 | } 10 | } 11 | int res = 0; 12 | for (int i = 0; i < 32; ++i) { 13 | res += (count[i] << i); 14 | } 15 | return res; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /LeetCode/single-number.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int singleNumber(int A[], int n) { 4 | int res; 5 | for (int i = 0; i < n; ++i) { 6 | res ^= A[i]; 7 | } 8 | return res; 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /LeetCode/sort-color.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void sortColors(int A[], int n) { 4 | auto it = partition(A, A+n, [&](int x) { return x == 0; }); 5 | partition(it, A+n, [&](int x) {return x == 1; }); 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /LeetCode/sort-list.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for singly-linked list. 3 | * struct ListNode { 4 | * int val; 5 | * ListNode *next; 6 | * ListNode(int x) : val(x), next(NULL) {} 7 | * }; 8 | */ 9 | class Solution { 10 | public: 11 | ListNode *getmid(ListNode *head) { 12 | if(head == nullptr || head->next == nullptr) return head; 13 | ListNode *slow=head, *fast=head; 14 | // Note here must be fast->next->next, when a->b->nullptr, slow should be a. 15 | while (fast->next && fast->next->next) { 16 | fast = fast->next->next; 17 | slow = slow->next; 18 | } 19 | return slow; 20 | } 21 | 22 | ListNode *merge(ListNode *l1, ListNode *l2) { 23 | ListNode dumpy(-1); 24 | ListNode *p = &dumpy; 25 | while (l1 != nullptr && l2 != nullptr) { 26 | if (l1->val < l2->val) { 27 | p->next = l1; 28 | l1 = l1->next; 29 | } else { 30 | p->next = l2; 31 | l2 = l2->next; 32 | } 33 | p = p->next; 34 | } 35 | if (l1) p->next = l1; 36 | if (l2) p->next = l2; 37 | return dumpy.next; 38 | } 39 | 40 | ListNode *sortList(ListNode *head) { 41 | if (head == nullptr || head->next == nullptr) return head; 42 | ListNode *mid = getmid(head); 43 | ListNode *first = head; 44 | ListNode *second = mid->next; 45 | mid->next = nullptr; 46 | 47 | first = sortList(first); 48 | second = sortList(second); 49 | return merge(first, second); 50 | } 51 | }; -------------------------------------------------------------------------------- /LeetCode/spiral-matrix-ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector > generateMatrix(int n) { 4 | vector > matrix; 5 | if (n == 0) return matrix; 6 | matrix = vector >(n, vector(n, 0)); 7 | 8 | int start_x = 0, start_y = 0; 9 | int end_x = n-1, end_y = n-1; 10 | int num = 1; 11 | while (true) { 12 | for (int j = start_y; j <= end_y; ++j) matrix[start_x][j] = num++; 13 | if (++start_x > end_x) break; 14 | for (int i = start_x; i <= end_x; ++i) matrix[i][end_y] = num++; 15 | if (--end_y < start_y) break; 16 | for (int j = end_y; j >= start_y; --j) matrix[end_x][j] = num++; 17 | if (--end_x < start_x) break; 18 | for (int i = end_x; i >= start_x; --i) matrix[i][start_y] = num++; 19 | if (++start_y > end_y) break; 20 | } 21 | return matrix; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /LeetCode/spiral-matrix.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector spiralOrder(vector > &matrix) { 4 | vector res; 5 | if (matrix.empty()) return res; 6 | int m = matrix.size(); 7 | int n = matrix[0].size(); 8 | int start_x = 0, start_y = 0; 9 | int end_x = m-1, end_y = n-1; 10 | while (true) { 11 | for (int j = start_y; j <= end_y; ++j) res.push_back(matrix[start_x][j]); 12 | if (++start_x > end_x) break; 13 | for (int i = start_x; i <= end_x; ++i) res.push_back(matrix[i][end_y]); 14 | if (--end_y < start_y) break; 15 | for (int j = end_y; j >= start_y; --j) res.push_back(matrix[end_x][j]); 16 | if (--end_x < start_x) break; 17 | for (int i = end_x; i >= start_x; --i) res.push_back(matrix[i][start_y]); 18 | if (++start_y > end_y) break; 19 | } 20 | return res; 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /LeetCode/sqrtx.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int sqrt(int x) { 4 | if (x <= 1) return x; 5 | int start = 1, end = x; 6 | int res = 1; 7 | while (start < end) { 8 | int mid = start + (end - start) / 2; 9 | if (mid == x / mid) { 10 | return mid; 11 | } else if(mid < x/mid) { 12 | start = mid + 1; 13 | res = mid; 14 | } else { 15 | end = mid; 16 | } 17 | } 18 | return res; 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /LeetCode/string-to-integer-atoi.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int atoi(const char *str) { 4 | while (*str == ' ') ++ str; 5 | bool neg = false; 6 | if (*str == '+' || *str == '-') { 7 | neg = *str == '-'; 8 | ++str; 9 | } 10 | int res = 0; 11 | while (*str != '\0') { 12 | if (!isdigit(*str)) break; 13 | int digit = (*str - '0'); 14 | if (res > INT_MAX / 10 || res == INT_MAX / 10 && digit> INT_MAX % 10) { 15 | return neg ? INT_MIN : INT_MAX; 16 | } 17 | res = res * 10 + digit; 18 | ++str; 19 | } 20 | return neg ? -res : res; 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /LeetCode/subsets-ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector > subsetsWithDup(vector &S) { 4 | vector > res; 5 | sort(S.begin(), S.end()); 6 | vector path; 7 | dfs(res, path, S, 0); 8 | sort(res.begin(), res.end()); 9 | return res; 10 | } 11 | 12 | void dfs(vector > &res, vector &path, vector &S, int start) { 13 | res.push_back(path); 14 | for (int i = start; i < S.size(); ++i) { 15 | if (i != start && S[i] == S[i-1]) continue; 16 | path.push_back(S[i]); 17 | dfs(res, path, S, i+1); 18 | path.pop_back(); 19 | } 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /LeetCode/subsets.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector > subsets(vector &S) { 4 | vector > res; 5 | sort(S.begin(), S.end()); 6 | vector path; 7 | dfs(res, path, S, 0); 8 | sort(res.begin(), res.end()); 9 | return res; 10 | } 11 | 12 | void dfs(vector > &res, vector &path, vector &S, int start) { 13 | if (start == S.size()) { 14 | res.push_back(path); 15 | return; 16 | } 17 | dfs(res, path, S, start+1); 18 | path.push_back(S[start]); 19 | dfs(res, path, S, start+1); 20 | path.pop_back(); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /LeetCode/substring-with-concatenation-of-all-words.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector findSubstring(string S, vector &L) { 4 | vector res; 5 | if (L.empty() || S.empty()) return res; 6 | int cnt = L.size(); 7 | int win = L[0].size(); 8 | unordered_map dict; 9 | for (auto const& x: L) ++dict[x]; 10 | 11 | /* 12 | for (int start = 0; start + win * cnt <= S.size(); ++start) { 13 | unordered_map temp(dict); 14 | for (int i = 0; i < cnt; ++i) { 15 | string word = S.substr(start + i*win, win); 16 | if (temp.find(word) == temp.end() || temp[word] == 0) break; 17 | --temp[word]; 18 | if (temp[word] == 0) temp.erase(word); 19 | } 20 | if (temp.empty()) res.push_back(start); 21 | } 22 | */ 23 | 24 | for (auto start = S.begin(); next(start, win*cnt) <= S.end(); ++start) { 25 | unordered_map temp(dict); 26 | for (int i = 0; i < cnt; ++i) { 27 | auto pos = temp.find(string(next(start, i*win), next(start, (i+1)*win))); 28 | if (pos == temp.end() || pos->second == 0) break; 29 | --pos->second; 30 | if (pos->second == 0) temp.erase(pos); 31 | } 32 | if (temp.empty()) res.push_back(distance(S.begin(), start)); 33 | } 34 | return res; 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /LeetCode/sudoku-solver.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void solveSudoku(vector > &board) { 4 | solve(board); 5 | } 6 | 7 | bool isValid(vector > &board, int row, int col) { 8 | for (int j = 0; j < 9; j++) if (j != col && board[row][j] == board[row][col]) return false; 9 | for (int i = 0; i < 9; i++) if (i != row && board[i][col] == board[row][col]) return false; 10 | for (int i = 3*(row/3); i < 3*(row/3)+3; i++) { 11 | for (int j = 3*(col/3); j < 3*(col/3)+3; j++) { 12 | if (i == row && j == col) continue; 13 | if (board[i][j] == board[row][col]) return false; 14 | } 15 | } 16 | return true; 17 | } 18 | 19 | bool solve(vector > &board) { 20 | int n = 9; 21 | for (int i = 0; i < n; i ++) { 22 | for (int j = 0; j < n; j ++) { 23 | if(board[i][j] == '.') { 24 | for (int k = 0; k < n; k++) { 25 | char c = '1' + k; 26 | board[i][j] = c; 27 | if (isValid(board, i, j) && solve(board)) return true; 28 | board[i][j] = '.'; 29 | } 30 | return false; 31 | } 32 | } 33 | } 34 | return true; 35 | } 36 | 37 | }; 38 | -------------------------------------------------------------------------------- /LeetCode/sum-root-to-leaf-numbers.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int dfs(TreeNode *root, int sum) 4 | { 5 | if(root == nullptr) return 0; 6 | if(root->left == nullptr && root->right == nullptr) { 7 | sum = sum * 10 + root->val; 8 | return sum; 9 | } 10 | return dfs(root->left, sum * 10 + root->val) + 11 | dfs(root->right, sum * 10 + root->val); 12 | } 13 | 14 | int sumNumbers(TreeNode *root) { 15 | return dfs(root, 0); 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /LeetCode/surrounded-regions.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void solve(vector> &board) { 4 | if (board.empty()) return; 5 | int n = board.size(); 6 | int m = board[0].size(); 7 | for (int i = 0; i < n; ++i) { 8 | bfs(board, i, 0); 9 | bfs(board, i, m-1); 10 | } 11 | for (int j = 0; j < m; ++j) { 12 | bfs(board, 0, j); 13 | bfs(board, n-1, j); 14 | } 15 | for (int i = 0; i < n; ++i) { 16 | for (int j = 0; j < m; ++j) { 17 | board[i][j] = (board[i][j] == 'L') ? 'O' : 'X'; 18 | } 19 | } 20 | } 21 | 22 | void bfs(vector> &board, int i, int j) { 23 | int n = board.size(); 24 | int m = board[0].size(); 25 | if (i < 0 || i >= n || j < 0 || j >= m) return; 26 | if (board[i][j] == 'O') { 27 | board[i][j] = 'L'; 28 | bfs(board, i+1, j); 29 | bfs(board, i-1, j); 30 | bfs(board, i, j+1); 31 | bfs(board, i, j-1); 32 | } 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /LeetCode/swap-nodes-in-pairs.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | ListNode *swapPairs(ListNode *head) { 4 | if (head == nullptr || head->next == nullptr) return head; 5 | ListNode *last = head->next->next; 6 | ListNode *newhead = head->next; 7 | newhead->next = head; 8 | head->next = swapPairs(head->next->next); 9 | return newhead; 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /LeetCode/symmetric-tree.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool isSymmetric(TreeNode *root) { 4 | if (root == nullptr) return true; 5 | return isSymmetric(root->left, root->right); 6 | } 7 | 8 | bool isSymmetric(TreeNode *left, TreeNode *right) { 9 | if (left == nullptr) return right == nullptr; 10 | if (right == nullptr) return left == nullptr; 11 | return left->val == right->val && 12 | isSymmetric(left->right, right->left) && isSymmetric(left->left, right->right); 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /LeetCode/text-justification.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector fullJustify(vector &words, int L) { 4 | vector res; 5 | vector v; 6 | int cur_len = 0, i = 0; 7 | string line; 8 | while (i < words.size()) { 9 | int space = (cur_len == 0) ? 0 : 1; 10 | if (cur_len + words[i].size() + space <= L) { 11 | v.push_back(words[i]); 12 | cur_len += (space + words[i].size()); 13 | ++i; 14 | } else { 15 | // cannot hold in this line. 16 | int total_space = L - cur_len; 17 | // A line other than the last line might contain only one word. 18 | if (v.size() == 1) { 19 | line = v[0]; 20 | line += string(total_space, ' '); 21 | } else { 22 | int per_space = total_space / (v.size() - 1); 23 | int left_space = total_space - per_space * (v.size()-1); 24 | line = v[0]; 25 | for (int w = 1; w < v.size(); ++w) { 26 | if (left_space >= 1) { 27 | line += ' '; 28 | --left_space; 29 | } 30 | line += string(per_space + 1, ' ') + v[w]; 31 | } 32 | } 33 | res.push_back(line); 34 | cur_len = 0; 35 | v.clear(); 36 | } 37 | } 38 | 39 | // process the last line. 40 | line = v[0]; 41 | for (int w = 1; w < v.size(); w++) line += ' ' + v[w]; 42 | line += string(L - cur_len, ' '); 43 | res.push_back(line); 44 | return res; 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /LeetCode/trapping-rain-water.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int trap(int A[], int n) { 4 | int cur_max = 0; 5 | int left[n], right[n]; 6 | for (int i = 0; i < n; i++) { 7 | left[i] = cur_max; 8 | cur_max = max(A[i], cur_max); 9 | } 10 | cur_max = 0; 11 | for (int i = n-1; i >= 0; i--) { 12 | right[i] = cur_max; 13 | cur_max = max(A[i], cur_max); 14 | } 15 | int sum = 0; 16 | for (int i = 0; i < n-1; i++) { 17 | sum += max(0, min(left[i], right[i]) - A[i]); 18 | } 19 | return sum; 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /LeetCode/triangle.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int minimumTotal(vector > &triangle) { 4 | if (triangle.empty()) return 0; 5 | int m = triangle.size(); 6 | vector f(m, INT_MAX); 7 | f[0] = 0; 8 | for (int i = 0; i < m; ++i) { 9 | for (int j = i; j >= 1; --j) { 10 | f[j] = min(f[j], f[j-1]) + triangle[i][j]; 11 | } 12 | f[0] = f[0] + triangle[i][0]; 13 | } 14 | return *min_element(f.begin(), f.end()); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /LeetCode/two-sum.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector twoSum(vector &numbers, int target) { 4 | unordered_map dict; 5 | for (int i = 0; i < numbers.size(); ++i) dict[numbers[i]] = i; 6 | for (int i = 0; i < numbers.size(); ++i) { 7 | auto pos = dict.find(target - numbers[i]); 8 | if (pos != dict.end() && i != pos->second) return {i + 1, pos->second + 1}; 9 | } 10 | return {}; 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /LeetCode/unique-binary-search-trees-ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector generate(int start, int end) { 4 | // CORNER CASE! MUST RETURN NULL SUBTREE 5 | if (start > end) return {nullptr}; 6 | vector res; 7 | for (int k = start; k <= end; ++k) { 8 | vector left = generate(start, k-1); 9 | vector right = generate(k+1, end); 10 | for (auto l: left) { 11 | for (auto r: right) { 12 | TreeNode *root = new TreeNode(k); 13 | root->left = l; 14 | root->right = r; 15 | res.push_back(root); 16 | } 17 | } 18 | } 19 | return res; 20 | } 21 | 22 | vector generateTrees(int n) { 23 | return generate(1, n); 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /LeetCode/unique-binary-search-trees.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int numTrees(int n) { 4 | vector f(n+1, 0); 5 | f[0] = 1; 6 | for(int i=1; i<=n; i++) { 7 | for(int k=0; k > &obstacleGrid) { 4 | if (obstacleGrid.empty()) return 0; 5 | int m = obstacleGrid.size(); 6 | int n = obstacleGrid[0].size(); 7 | 8 | vector f(n, 0); 9 | f[0] = obstacleGrid[0][0] ? 0 : 1; 10 | for (int i = 0; i < m; ++i) { 11 | for (int j = 0; j < n; ++j) { 12 | f[j] = obstacleGrid[i][j] ? 0 : (f[j] + (j == 0 ? 0 : f[j-1])); 13 | } 14 | } 15 | return f[n-1]; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /LeetCode/unique-paths.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | /* 4 | // f(i, j) = f(i-1, j) + f(i, j-1) 5 | int uniquePaths(int m, int n) { 6 | vector > f(m, vector(n, 0)); 7 | for (int i = 0; i < m; ++i) f[i][0] = 1; 8 | for (int j = 0; j < n; ++j) f[0][j] = 1; 9 | for (int i = 1; i < m; ++i) { 10 | for (int j = 1; j < n; ++j) { 11 | f[i][j] = f[i-1][j] + f[i][j-1]; 12 | } 13 | } 14 | return f[m-1][n-1]; 15 | } 16 | */ 17 | 18 | int uniquePaths(int m, int n) { 19 | vector f(n, 1); 20 | for (int i = 1; i < m; ++i) { 21 | for (int j = 1; j < n; ++j) { 22 | f[j] = f[j] + f[j-1]; 23 | } 24 | } 25 | return f[n-1]; 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /LeetCode/valid-number.cpp: -------------------------------------------------------------------------------- 1 | lass Solution { 2 | public: 3 | bool isNumber(const char *s) { 4 | int len = strlen(s); 5 | if (len == 0) return false; 6 | while (*s == ' ') ++s; 7 | 8 | int dotCount = 0, expCount = 0; 9 | // define some tags, start of number, exp tag occured, need for number input 10 | bool start = true, preExp = false, hasNum = false; 11 | while(*s != '\0') { 12 | if (*s == ' ') break; 13 | if (*s == '+' || *s == '-') { 14 | if (!start && !preExp) return false; 15 | } else if (isdigit(*s)) { 16 | hasNum = true; 17 | preExp = false; 18 | } else if (*s == '.') { 19 | dotCount += 1; 20 | preExp = false; 21 | if(expCount >= 1) return false; 22 | } else if(*s == 'e' || *s == 'E') { 23 | if (!hasNum) return false; 24 | expCount += 1; 25 | hasNum = false; 26 | preExp = true; 27 | } else return false; 28 | 29 | start = false; 30 | if(dotCount > 1 || expCount > 1) return false; 31 | ++s; 32 | } 33 | 34 | if (!hasNum) return false; 35 | while(*s == ' ') ++s; 36 | return *s == '\0'; 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /LeetCode/valid-palindrome.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool isPalindrome(string s) { 4 | auto start = s.begin(), end = s.end() - 1; 5 | while (start < end) { 6 | while (!isalnum(*start) && start < end) ++start; 7 | while (!isalnum(*end) && start < end) --end; 8 | if (start == end) return true; 9 | if (tolower(*start) != tolower(*end)) return false; 10 | ++start; 11 | --end; 12 | } 13 | return true; 14 | } 15 | }; -------------------------------------------------------------------------------- /LeetCode/valid-parentheses.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool isValid(string s) { 4 | stack stk; 5 | unordered_map dict; 6 | dict['('] = dict[')'] = 1; 7 | dict['['] = dict[']'] = 2; 8 | dict['{'] = dict['}'] = 3; 9 | 10 | for (int i=0; i > &board) { 4 | vector used(9); 5 | for (int i = 0; i < 9; ++i) { 6 | fill(used.begin(), used.end(), false); 7 | for (int j = 0; j < 9; ++j) { 8 | char x = board[i][j]; 9 | if (x == '.') continue; 10 | if (used[x-'1']) return false; 11 | used[x-'1'] = true; 12 | } 13 | fill(used.begin(), used.end(), false); 14 | for (int j = 0; j < 9; ++j) { 15 | char x = board[j][i]; 16 | if (x == '.') continue; 17 | if (used[x-'1']) return false; 18 | used[x-'1'] = true; 19 | } 20 | } 21 | 22 | for (int r = 0; r < 3; ++r) { 23 | for (int c = 0; c < 3; ++c) { 24 | fill(used.begin(), used.end(), false); 25 | for (int i = r*3; i < r*3+3; ++i) { 26 | for (int j = c*3; j < c*3+3; ++j) { 27 | char x = board[i][j]; 28 | if (x == '.') continue; 29 | if (used[x-'1']) return false; 30 | used[x-'1'] = true; 31 | } 32 | } 33 | } 34 | } 35 | 36 | return true; 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /LeetCode/validate-binary-search-tree-bottom-up.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool isValidBST(TreeNode *root) { 4 | if (root == nullptr) return true; 5 | auto p = getRange(root); 6 | return p.first <= p.second; 7 | } 8 | 9 | pair getRange(TreeNode *root) { 10 | auto res = make_pair(root->val, root->val); 11 | if (root->left) { 12 | auto l = getRange(root->left); 13 | if (l.first > l.second) return make_pair(0, -1); 14 | if (root->val <= l.second) return make_pair(0, -1); 15 | res.first = l.first; 16 | } 17 | if (root->right) { 18 | auto r = getRange(root->right); 19 | if (r.first > r.second) return make_pair(0, -1); 20 | if (root->val >= r.first) return make_pair(0, -1); 21 | res.second = r.second; 22 | } 23 | return res; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /LeetCode/validate-binary-search-tree.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool isValidBST(TreeNode *root) { 4 | return valid(root, INT_MAX, INT_MIN); 5 | } 6 | 7 | bool valid(TreeNode *root, int maxval, int minval) { 8 | if(root == nullptr) return true; 9 | if(root->val <= minval || root->val >= maxval) return false; 10 | return valid(root->left, root->val, minval) && 11 | valid(root->right, maxval, root->val); 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /LeetCode/wildcard-matching.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool isMatch(const char *s, const char *p) { 4 | const char *str = s; 5 | const char *ptr = p; 6 | bool star = false; 7 | while(*str != '\0') { 8 | if(*ptr == '?') { 9 | ++ptr; 10 | ++str; 11 | } else if(*ptr == '*') { 12 | s = str; 13 | p = ptr; 14 | star = true; 15 | while(*p == '*') ++p; 16 | if(*p == '\0') return true; 17 | str = s; 18 | ptr = p; 19 | } else if(*ptr != *str) { 20 | if(!star) return false; 21 | else { 22 | s++; 23 | str = s; 24 | ptr = p; 25 | } 26 | } else { // *ptr == *str 27 | ++ptr; 28 | ++str; 29 | } 30 | } 31 | while(*ptr == '*') ++ptr; 32 | return (*ptr == '\0'); 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /LeetCode/word-break-ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void genpath(vector > &p, vector &path, vector &res, string s, int cur) { 4 | if (cur == 0) { 5 | string output; 6 | for (auto rit = path.rbegin(); rit != path.rend(); ++rit) { 7 | output += *rit + " "; 8 | } 9 | output.erase(output.end() - 1); 10 | res.push_back(output); 11 | return; 12 | } 13 | 14 | for (int i = 0; i < s.size(); ++i) { 15 | if (p[cur][i]) { 16 | path.push_back(s.substr(i, cur-i)); 17 | genpath(p, path, res, s, i); 18 | path.pop_back(); 19 | } 20 | } 21 | } 22 | 23 | vector wordBreak(string s, unordered_set &dict) { 24 | int n = s.size(); 25 | vector f(n+1, false); 26 | vector res; 27 | f[0] = true; 28 | vector > p(n+1, vector(n, false)); 29 | for (int k = 1; k <= n; k++) { 30 | for (int i = 0; i < k; i++) { 31 | string subword = s.substr(i, k-i); 32 | if (f[i] && dict.count(subword) != 0) { 33 | f[k] = true; 34 | p[k][i] = true; 35 | } 36 | } 37 | } 38 | 39 | vector path; 40 | if (f[n]) genpath(p, path, res, s, s.size()); 41 | return res; 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /LeetCode/word-break.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool wordBreak(string s, unordered_set &dict) { 4 | int n = s.size(); 5 | vector f(n+1, false); 6 | f[0] = true; 7 | // f[i] means prefix s with len=i can be segmented by dict 8 | for (int i = 1; i <= n; ++i) { 9 | for (int j = 0; j < i; ++j) { 10 | if (f[j] && dict.find(s.substr(j, i-j)) != dict.end()) { 11 | f[i] = true; 12 | break; 13 | } 14 | } 15 | } 16 | return f[n]; 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /LeetCode/word-ladder-ii.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void gen_path(vector> &res, unordered_map > &parents, 4 | vector &path, string &start, string &word) { 5 | path.push_back(word); 6 | if (start == word) { 7 | res.push_back(path); 8 | reverse(res.back().begin(), res.back().end()); 9 | } else { 10 | for (auto s: parents[word]) { 11 | gen_path(res, parents, path, start, s); 12 | } 13 | } 14 | path.pop_back(); 15 | } 16 | 17 | vector> findLadders(string start, string end, unordered_set &dict) { 18 | vector> res; 19 | if (start.size() != end.size()) return res; 20 | unordered_set visited; 21 | unordered_map > parents; 22 | unordered_set current, next; 23 | current.insert(start); 24 | visited.insert(start); 25 | bool flag = false; 26 | while (!current.empty() && !flag) { 27 | for (auto word: current) visited.insert(word); 28 | for (auto word: current) { 29 | for (int i = 0; i < word.size(); ++i) { 30 | string origin = word; 31 | for (char c = 'a'; c <= 'z'; ++c) { 32 | if (c == origin[i]) continue; 33 | word[i] = c; 34 | if (word == end) flag = true; 35 | if (dict.count(word) && visited.count(word) == 0) { 36 | next.insert(word); 37 | parents[word].push_back(origin); 38 | } 39 | } 40 | word[i] = origin[i]; 41 | } 42 | } 43 | current.clear(); 44 | current.swap(next); 45 | } 46 | vector path; 47 | if (flag) gen_path(res, parents, path, start, end); 48 | return res; 49 | } 50 | }; -------------------------------------------------------------------------------- /LeetCode/word-ladder.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int ladderLength(string start, string end, unordered_set &dict) { 4 | if (start.size() != end.size()) return 0; 5 | unordered_set visited; 6 | queue current, next; 7 | current.push(start); 8 | visited.insert(start); 9 | int len = 0; 10 | while (!current.empty()) { 11 | len += 1; 12 | while (!current.empty()) { 13 | string word = current.front(); 14 | current.pop(); 15 | if (word == end) return len; 16 | for (int i = 0; i < word.size(); ++i) { 17 | char tmp = word[i]; 18 | for (char c = 'a'; c <= 'z'; ++c) { 19 | word[i] = c; 20 | if (dict.count(word) && visited.count(word) == 0) { 21 | next.push(word); 22 | visited.insert(word); 23 | } 24 | } 25 | word[i] = tmp; 26 | } 27 | } 28 | current.swap(next); 29 | } 30 | return 0; 31 | } 32 | }; -------------------------------------------------------------------------------- /LeetCode/word-search.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool dfs(vector > &board, vector > &visited, const string &word, int cur, int i, int j) { 4 | if (cur == word.size()) return true; 5 | 6 | int m = board.size(); 7 | int n = board[0].size(); 8 | if (i < 0 || i >= m || j < 0 || j >= n) return false; 9 | if (visited[i][j]) return false; 10 | 11 | bool ret = false; 12 | visited[i][j] = true; 13 | if (board[i][j] == word[cur]) { 14 | ret = dfs(board, visited, word, cur+1, i+1, j) || dfs(board, visited, word, cur+1, i-1, j) || 15 | dfs(board, visited, word, cur+1, i, j+1) || dfs(board, visited, word, cur+1, i, j-1); 16 | } 17 | visited[i][j] = false; 18 | return ret; 19 | } 20 | 21 | bool exist(vector > &board, string word) { 22 | if (board.empty()) return false; 23 | int m = board.size(); 24 | int n = board[0].size(); 25 | vector > visited(m, vector(n, false)); 26 | for (int i = 0; i < m; ++i) { 27 | for (int j = 0; j < n; ++j) { 28 | if(dfs(board, visited, word, 0, i, j)) return true; 29 | } 30 | } 31 | return false; 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /LeetCode/zigzag-conversion.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | string convert(string s, int nRows) { 4 | if (nRows <= 1) return s; 5 | vector > v(nRows); 6 | bool zig=true; 7 | auto it = s.begin(); 8 | int zigRow = 0; 9 | while (it != s.end()) { 10 | if (zig) { 11 | for (int r = 0; r < nRows; ++r) { 12 | if (it == s.end()) break; 13 | v[r].push_back(*it); 14 | ++it; 15 | } 16 | zigRow = nRows-2; 17 | if (zigRow != 0) zig = false; 18 | } else { 19 | v[zigRow].push_back(*it); 20 | ++it; 21 | --zigRow; 22 | if (zigRow == 0) zig = true; 23 | } 24 | } 25 | string res; 26 | for (const auto &x: v) 27 | for (const auto &y: x) 28 | res += y; 29 | return res; 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /MockInterview/build: -------------------------------------------------------------------------------- 1 | if [ -z "$1" ] 2 | then 3 | echo "No argu supplied" 4 | exit 1 5 | fi 6 | name=$1 7 | echo compile and run $name 8 | g++ -c $name.cpp -std=c++11 9 | g++ $name.o -o $name.out 10 | ./$name.out 11 | rm $name.out 12 | rm $name.o 13 | -------------------------------------------------------------------------------- /MockInterview/compute-process-time.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | // input: ABAAABBC interval = 3 4 | // AB__A___A___AB___BC 5 | 6 | 7 | int computeTime(const string& input, int interval) { 8 | int a = 0, b = 0, c = 0; 9 | int res = 0; 10 | for (const auto& s: input) { 11 | if (s == 'A') { 12 | res += a + 1; 13 | a = interval + 1; 14 | } 15 | if (s == 'B') { 16 | res += b + 1; 17 | b = interval + 1; 18 | } 19 | if (s == 'C') { 20 | res += c + 1; 21 | c = interval + 1; 22 | } 23 | if (a > 0) a -= 1; 24 | if (b > 0) b -= 1; 25 | if (c > 0) c -= 1; 26 | } 27 | return res; 28 | } 29 | 30 | int main() { 31 | cout << computeTime("ABAAABBC", 3) << endl; 32 | } 33 | -------------------------------------------------------------------------------- /MockInterview/delete-node.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | // Given a binary search tree and a range [a,b] 7 | // Delete all nodes whose values are not in this range 8 | 9 | struct TreeNode { 10 | int val; 11 | TreeNode *left; 12 | TreeNode *right; 13 | TreeNode(int x) : val(x), left(NULL), right(NULL) {} 14 | }; 15 | 16 | void inorderTraversal(TreeNode *root) { 17 | TreeNode *cur = root; 18 | stack s; 19 | while (!s.empty() || cur != nullptr) { 20 | if (cur != nullptr) { 21 | s.push(cur); 22 | cur = cur->left; 23 | } else { 24 | cur = s.top(); 25 | s.pop(); 26 | cout << cur->val << " "; 27 | cur = cur->right; 28 | } 29 | } 30 | cout << endl; 31 | } 32 | 33 | 34 | template 35 | TreeNode *sortedArrayToBST(BidIt start, BidIt end) { 36 | if (start == end) return nullptr; 37 | auto mid = start + distance(start, end) / 2; 38 | TreeNode *root = new TreeNode(*mid); 39 | root->left = sortedArrayToBST(start, mid); 40 | root->right = sortedArrayToBST(mid+1, end); 41 | return root; 42 | } 43 | 44 | TreeNode *deleteNode(TreeNode *root, int a, int b) { 45 | if (root == nullptr) return root; 46 | TreeNode *left = deleteNode(root->left, a, b); 47 | TreeNode *right = deleteNode(root->right, a, b); 48 | if (root->val < a || root->val > b) { 49 | if (root->left) { 50 | root = root->left; 51 | } else if (root->right) { 52 | root = root->right; 53 | } else { 54 | return nullptr; 55 | } 56 | } else { 57 | root->left = left; 58 | root->right = right; 59 | } 60 | return root; 61 | } 62 | 63 | int main() { 64 | vector num = {15, 20, 30, 35, 40, 45, 50}; 65 | TreeNode *root = sortedArrayToBST(num.begin(), num.end()); 66 | inorderTraversal(root); 67 | root = deleteNode(root, 25, 35); 68 | inorderTraversal(root); 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /MockInterview/first-duplicate-num.cpp: -------------------------------------------------------------------------------- 1 | // Given an array of integer, range from 1..n-1, find the first (min) duplicate number 2 | // Example, A = {2, 1, 1, 3, 4} result = 1 3 | 4 | #include 5 | using namespace std; 6 | 7 | int firstDuplicateNum(int A[], int n) { 8 | int res = n; 9 | for (int i = 0; i < n; ++i) { 10 | while (A[i] != i + 1 && A[i] >= 1 && A[i] < n) { 11 | if (A[i] == A[A[i] - 1]) { 12 | res = min(res, A[i]); 13 | break; 14 | } else swap(A[i], A[A[i]-1]); 15 | } 16 | } 17 | return res; 18 | } 19 | 20 | int main() { 21 | int A[] = {4, 1, 2, 4, 2}; 22 | cout << firstDuplicateNum(A, 5) << endl; 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /MockInterview/json-parser.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | void parseJson(string str) { 5 | auto it = str.begin(); 6 | bool has_left = false; 7 | int level = 0; 8 | string temp; 9 | while (it != str.end()) { 10 | if (*it == '\'') { 11 | if (has_left) { 12 | cout << temp; 13 | temp = ""; 14 | has_left = false; 15 | } else { 16 | has_left = true; 17 | } 18 | } else if (*it == ':') { 19 | cout << ":"; 20 | } else if (*it == '[') { 21 | level += 4; 22 | cout << endl << string(level, ' ') << "[" << endl; 23 | cout << string(level, ' '); 24 | } else if (*it == ']') { 25 | cout << endl << string(level, ' ') << "]" << endl; 26 | level -= 4; 27 | } else if (*it == '{' || *it == '}') { 28 | // do nothing 29 | } else if (*it == ',') { 30 | cout << endl; 31 | cout << string(level, ' '); 32 | } else { 33 | temp += *it; 34 | } 35 | ++it; 36 | } 37 | } 38 | 39 | int main() { 40 | string str = "{'a':'1','b':['c':'2','d':'3','e':['f':'6','g':'7']]}"; 41 | parseJson(str); 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #Cracking The Coding Interview 2 | Now it's a repo for interviews, including solutions for: 3 | 4 | * CC150 5 | * EPI: Elements of Programming Interviews 6 | * LeetCode 7 | * Geeks4Geeks 8 | * Mock Interview 9 | --------------------------------------------------------------------------------