├── .gitignore ├── CPPLINT.cfg ├── LICENSE ├── README.md ├── codeforces ├── ability-to-convert │ ├── Makefile │ ├── README.md │ └── main.cpp ├── broken-tree │ ├── Makefile │ ├── README.md │ └── main.cpp ├── cards-sorting │ ├── Makefile │ ├── README.md │ └── main.cpp ├── dna-evolution │ ├── Makefile │ ├── README.md │ └── main.cpp ├── exam-cheating │ ├── Makefile │ ├── README.md │ └── main.cpp ├── fedor-and-coupons │ ├── Makefile │ ├── README.md │ └── main.cpp ├── geometric-progression │ ├── Makefile │ ├── README.md │ └── main.cpp ├── innokenty-and-a-football-league │ ├── Makefile │ ├── README.md │ └── main.cpp ├── interactive-bulls-and-cows-easy │ ├── Makefile │ ├── README.md │ └── main.cpp ├── interactive-bulls-and-cows-hard │ ├── Makefile │ ├── README.md │ └── main.cpp ├── karen-and-supermarket │ ├── Makefile │ ├── README.md │ └── main.cpp ├── leaving-auction │ ├── Makefile │ ├── README.md │ └── main.cpp ├── little-girl-and-maximum-sum │ ├── Makefile │ ├── README.md │ └── main.cpp ├── mike-and-feet │ ├── Makefile │ ├── README.md │ └── main.cpp ├── mister-b-and-flight-to-the-moon │ ├── README.md │ └── main.py ├── mister-b-and-pr-shifts │ ├── Makefile │ ├── README.md │ └── main.cpp ├── multicolored-cars │ ├── README.md │ └── main.py ├── new-year-and-fireworks │ ├── Makefile │ ├── README.md │ └── main.cpp ├── paths-in-complete-binary-tree │ ├── Makefile │ ├── README.md │ └── main.cpp ├── police-stations │ ├── Makefile │ ├── README.md │ └── main.cpp ├── running-with-obstacles │ ├── Makefile │ ├── README.md │ └── main.cpp ├── template │ ├── Makefile │ ├── README.md │ └── main.cpp ├── the-bakery │ ├── Makefile │ ├── README.md │ └── main.cpp ├── the-penguins-game │ ├── Makefile │ ├── README.md │ └── main.cpp ├── towers │ ├── Makefile │ ├── README.md │ └── main.cpp ├── underground-lab │ ├── Makefile │ ├── README.md │ └── main.cpp └── xenia-and-tree │ ├── Makefile │ ├── README.md │ └── main.cpp ├── geeks-for-geeks ├── dynamic-programming │ └── set-18-partition-problem │ │ ├── README.md │ │ └── solution.py ├── linked-lists │ └── flatten-multi-level-list │ │ ├── README.md │ │ └── flatten.py └── mathematics │ └── weighted-random-generator │ ├── README.md │ ├── generators.py │ ├── generators_test.py │ ├── range_map.py │ ├── range_map_test.py │ └── test.sh ├── hacker-rank ├── algorithms │ ├── bit-manipulation │ │ ├── and-product │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── main.cpp │ │ ├── cipher │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── main.cpp │ │ └── flipping-bits │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── main.cpp │ ├── dynamic-programming │ │ ├── candies │ │ │ ├── README.md │ │ │ └── candies.py │ │ ├── coin-change │ │ │ ├── README.md │ │ │ └── coin-change.py │ │ ├── fibonacci-modified │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── Solution.java │ │ ├── grid-walking │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── main.cpp │ │ ├── longest-common-subsequence │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── main.cpp │ │ ├── longest-increasing-subsequence │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── main.cpp │ │ │ └── solution.py │ │ ├── maximum-subarray │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── main.cpp │ │ ├── square-subsequences │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── main.cpp │ │ ├── stock-maximize │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── main.cpp │ │ └── summing-pieces │ │ │ ├── README.md │ │ │ └── solution.py │ ├── graph-theory │ │ ├── bfs-shortest-reach │ │ │ ├── README.md │ │ │ └── bfs-shortest-reach.py │ │ ├── crab-graphs │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── main.cpp │ │ ├── dijkstra-shortest-reach-2 │ │ │ ├── README.md │ │ │ └── dijkstra-shortest-reach-2.py │ │ ├── floyd-city-of-blinding-lights │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── floyd_warshall.py │ │ │ └── main.cpp │ │ ├── jack-goes-to-rapture │ │ │ ├── README.md │ │ │ └── jack-goes-to-rapture.py │ │ ├── journey-to-the-moon │ │ │ ├── README.md │ │ │ └── journey-to-the-moon.py │ │ ├── kruskal-mst-really-special-subtree │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── main.cpp │ │ ├── prims-mst-special-subtree │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── main.cpp │ │ │ └── prims-mst.py │ │ └── scc │ │ │ ├── README.md │ │ │ └── scc.py │ ├── implementation │ │ └── matrix-rotation │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── main.cpp │ ├── search │ │ ├── connected-cell-in-a-grid │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── main.cpp │ │ ├── cut-the-tree │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── Solution.java │ │ ├── max-sum-k-non-adjacent │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── generator.py │ │ │ └── main.cpp │ │ ├── maximise-sum │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── Solution.java │ │ ├── missing-numbers │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── main.cpp │ │ ├── pairs │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── main.cpp │ │ ├── playing-with-numbers │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── main.cpp │ │ ├── sherlock-and-array │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── SherlockAndArray.java │ │ └── short-palindrome │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── main.cpp │ ├── sorting │ │ └── quicksort-in-place │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── Solution.java │ └── strings │ │ ├── bigger-is-greater │ │ ├── Makefile │ │ ├── README.md │ │ └── Solution.java │ │ ├── common-child │ │ ├── Makefile │ │ ├── README.md │ │ └── main.cpp │ │ ├── pangrams │ │ ├── Makefile │ │ ├── README.md │ │ └── Solution.java │ │ ├── sherlock-and-anagrams │ │ ├── Makefile │ │ ├── README.md │ │ └── Solution.java │ │ └── two-strings │ │ ├── README.md │ │ └── two-strings.py ├── artificial-intelligence │ └── alpha-beta-pruning │ │ └── tic-tac-toe │ │ ├── README.md │ │ └── solution.py ├── data-structures │ ├── disjoint-set │ │ └── merging-communities │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── main.cpp │ ├── heap │ │ └── find-median │ │ │ ├── README.md │ │ │ └── find-median.py │ ├── tree │ │ ├── bst-lowest-common-ancestor │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── main.cpp │ │ ├── median-updates │ │ │ ├── README.md │ │ │ └── median-updates.py │ │ └── self-balancing-tree │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── main.cpp │ └── trie │ │ └── no-prefix-set │ │ ├── Makefile │ │ ├── README.md │ │ └── Solution.java └── mathematics │ └── combinatorics │ ├── choose-and-calculate │ ├── Makefile │ ├── README.md │ └── main.cpp │ ├── journey-to-mars │ ├── Makefile │ ├── README.md │ └── main.cpp │ ├── ncr-table │ ├── Makefile │ ├── README.md │ └── main.cpp │ └── rank-of-a-word │ ├── README.md │ └── solution.py ├── leetcode └── algorithms │ ├── 4sum │ ├── README.md │ └── solution.py │ ├── basic-calculator │ ├── README.md │ └── solution.py │ ├── binary-tree-inorder-postorder │ ├── Makefile │ ├── README.md │ └── Solution.java │ ├── binary-tree-inorder-preorder │ ├── Makefile │ ├── README.md │ ├── Solution.java │ └── solution.py │ ├── binary-tree-max-path-sum │ ├── README.md │ └── solution.py │ ├── binary-tree-zigzag-level-order │ ├── README.md │ └── solution.py │ ├── burst-balloons │ ├── README.md │ └── solution.py │ ├── closest-palindrome │ ├── Makefile │ ├── README.md │ └── main.cpp │ ├── container-with-most-water │ ├── README.md │ └── solution.py │ ├── contains-duplicate-iii │ ├── Makefile │ ├── README.md │ ├── main.cpp │ └── solution.py │ ├── data-stream-disjoint-intervals │ ├── Makefile │ ├── README.md │ └── main.cpp │ ├── different-ways-to-add-parenthesis │ ├── README.md │ └── solution.py │ ├── distinct-subsequences │ ├── README.md │ └── solution.py │ ├── dungeon-game │ ├── README.md │ └── solution.py │ ├── edit-distance │ ├── Makefile │ ├── README.md │ ├── Solution.java │ └── solution.py │ ├── encode-string-with-shortest-length │ ├── README.md │ └── solution.py │ ├── flatten-binary-tree │ ├── README.md │ └── solution.py │ ├── game-of-life │ ├── Makefile │ ├── README.md │ └── Solution.java │ ├── gas-station │ ├── README.md │ └── solution.py │ ├── interleaving-string │ ├── README.md │ └── solution.py │ ├── is-balanced │ ├── Makefile │ ├── README.md │ └── Solution.java │ ├── k-pairs-with-smallest-sums │ ├── Makefile │ ├── README.md │ └── Solution.java │ ├── kth-largest-element │ ├── Makefile │ ├── README.md │ └── Solution.java │ ├── kth-smallest-element-in-sorted-matrix │ ├── README.md │ └── solution.py │ ├── largest-rectangle-in-histogram │ ├── README.md │ └── solution.py │ ├── lca-binary-tree │ ├── Makefile │ ├── README.md │ └── Solution.java │ ├── lexicographical-numbers │ ├── Makefile │ ├── README.md │ └── main.cpp │ ├── lfu-cache │ ├── LFUCache.java │ ├── Makefile │ └── README.md │ ├── libs │ ├── ListNode.java │ ├── Makefile │ ├── Point.java │ └── TreeNode.java │ ├── linked-list-cycle-ii │ ├── README.md │ └── solution.py │ ├── longest-valid-parenthesis │ ├── README.md │ └── solution.py │ ├── majority-element-ii │ ├── README.md │ └── solution.py │ ├── max-points-on-a-line │ ├── Makefile │ ├── README.md │ └── Solution.java │ ├── maximum-gap │ ├── README.md │ └── solution.py │ ├── median-of-two-sorted-arrays │ ├── Makefile │ ├── README.md │ ├── Solution.java │ └── solution.py │ ├── mini-parser │ ├── README.md │ └── solution.py │ ├── minimum-height-tree │ ├── Makefile │ ├── README.md │ └── main.cpp │ ├── minimum-window-substring │ ├── README.md │ └── solution.py │ ├── n-queens-ii │ ├── Makefile │ ├── README.md │ └── main.cpp │ ├── non-overlapping-intervals │ ├── README.md │ └── solution.py │ ├── palindrome-linked-list │ ├── Makefile │ ├── README.md │ └── Solution.java │ ├── palindrome-pairs │ ├── README.md │ └── solution.py │ ├── permutation-sequence │ ├── Makefile │ ├── README.md │ └── main.cpp │ ├── permutations-ii │ ├── Makefile │ ├── README.md │ └── main.cpp │ ├── range-sum-query-mutable │ ├── Makefile │ ├── README.md │ └── main.cpp │ ├── recover-binary-tree │ ├── README.md │ └── solution.py │ ├── rectangle-area │ ├── Makefile │ ├── README.md │ └── Solution.java │ ├── regular-expression-matching │ ├── Makefile │ ├── README.md │ └── Solution.java │ ├── remove-duplicates-from-sorted-array-ii │ ├── README.md │ └── solution.py │ ├── remove-k-digits │ ├── README.md │ └── solution.py │ ├── reverse-nodes-k-group │ ├── README.md │ └── solution.py │ ├── reverse-words-in-a-string │ ├── Makefile │ ├── README.md │ └── main.cpp │ ├── rotate-image │ ├── Makefile │ ├── README.md │ └── Solution.java │ ├── set-matrix-zeroes │ ├── Makefile │ ├── README.md │ └── Solution.java │ ├── shortest-palindrome │ ├── Makefile │ ├── README.md │ └── main.cpp │ ├── skyline │ ├── Makefile │ ├── README.md │ ├── Solution.java │ └── skyline.py │ ├── sliding-window-maximum │ ├── README.md │ └── solution.py │ ├── sorted-array-to-bst │ ├── Makefile │ ├── README.md │ └── Solution.java │ ├── spiral-matrix │ ├── Makefile │ ├── README.md │ ├── Solution.java │ └── solution.py │ ├── sqrt │ ├── README.md │ └── solution.py │ ├── stock-profit-iii │ ├── README.md │ └── solution.py │ ├── stock-profit-iv │ ├── Makefile │ ├── README.md │ └── Solution.java │ ├── subsets-ii │ ├── Makefile │ ├── README.md │ └── main.cpp │ ├── substring-concat-all-words │ ├── README.md │ └── solution.py │ ├── sudoku-solver │ ├── README.md │ └── solution.py │ ├── unique-substrings-wraparound-string │ ├── README.md │ └── solution.py │ ├── validate-bst │ ├── Makefile │ ├── README.md │ └── Solution.java │ ├── wiggle-subsequence │ ├── README.md │ └── solution.py │ ├── wildcard-matching │ ├── README.md │ └── solution.py │ └── word-break │ ├── README.md │ └── solution.py ├── lib ├── cpp │ ├── kmp │ │ ├── Makefile │ │ ├── README.md │ │ └── main.cpp │ ├── manachers │ │ ├── Makefile │ │ ├── README.md │ │ └── main.cpp │ └── z-algorithm │ │ ├── Makefile │ │ ├── README.md │ │ └── main.cpp └── python │ ├── kmp │ ├── README.md │ └── kmp.py │ └── manachers │ ├── README.md │ └── manachers.py └── linter.sh /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | __pycache__ 3 | .vscode 4 | *.class 5 | *.swp 6 | -------------------------------------------------------------------------------- /CPPLINT.cfg: -------------------------------------------------------------------------------- 1 | filter=-legal/copyright,-build/include,-build/c++11,-runtime/references,-runtime/string 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Andrei Maximov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /codeforces/ability-to-convert/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++14 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /codeforces/ability-to-convert/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://codeforces.com/problemset/problem/758/D](http://codeforces.com/problemset/problem/758/D) 4 | -------------------------------------------------------------------------------- /codeforces/ability-to-convert/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; // NOLINT 4 | 5 | // 6 | // Entry for optimal decoding of a suffix of a string k. 7 | // 8 | struct cache { 9 | // 10 | // The minimal decoding. 11 | // 12 | uint64_t n; 13 | 14 | // 15 | // If the encoding in the original base has i digits, this is base^i. This is 16 | // essentially the value we need to multiply a digit x if we wish to prepend 17 | // x to the original encoding. 18 | // 19 | uint64_t power; 20 | }; 21 | 22 | string convert(uint32_t n, const string& k) { 23 | // Track optimal encoding for each suffix k[i...]. 24 | vector dp(k.size() + 1); 25 | dp[k.size()] = {0, 1}; 26 | 27 | for (int i = k.size() - 1; i >= 0; i--) { 28 | // 0 is the only digit that can start with a 0 in an encoding. Multiple 0's 29 | // are not valid. 30 | if (k[i] == '0') { 31 | dp[i] = {dp[i + 1].n, dp[i + 1].power * n}; 32 | continue; 33 | } 34 | 35 | // 36 | // For each suffix k[i...] consider possible splits k[i...j]k[j + 1...]. 37 | // 38 | for (size_t j = i; j < k.size(); j++) { 39 | uint64_t prefix = stoull(k.substr(i, j - i + 1)); 40 | if (prefix >= n) { 41 | break; 42 | } 43 | 44 | uint64_t power = dp[j + 1].power; 45 | 46 | // The result is <= 10^18, so make sure we do not encounter overflow 47 | // when using uint64_t which has an upper bound > 10^18 to consider a 48 | // candidate decoding. 49 | if (numeric_limits::max() / prefix < power) { 50 | continue; 51 | } 52 | 53 | // Compute a candidate an duse it if it is better than en existing one 54 | // for suffix k[i...]. 55 | uint64_t x = prefix * power + dp[j + 1].n; 56 | if (dp[i].power == 0 || x < dp[i].n) { 57 | dp[i] = {x, power * n}; 58 | } 59 | } 60 | } 61 | 62 | return to_string(dp[0].n); 63 | } 64 | 65 | int main() { 66 | uint32_t n; 67 | cin >> n; 68 | string k; 69 | cin >> k; 70 | 71 | cout << convert(n, k) << endl; 72 | return 0; 73 | } 74 | 75 | -------------------------------------------------------------------------------- /codeforces/broken-tree/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++14 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /codeforces/broken-tree/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://codeforces.com/problemset/problem/758/E](http://codeforces.com/problemset/problem/758/E) 4 | 5 | -------------------------------------------------------------------------------- /codeforces/cards-sorting/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++14 -Wall -o out 3 | 4 | default: out run 5 | 6 | out: main.cpp 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /codeforces/cards-sorting/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://codeforces.com/problemset/problem/830/B](http://codeforces.com/problemset/problem/830/B) 4 | -------------------------------------------------------------------------------- /codeforces/dna-evolution/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++14 -Wall -o out 3 | 4 | default: out run 5 | 6 | out: main.cpp 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /codeforces/dna-evolution/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://codeforces.com/problemset/problem/827/C](http://codeforces.com/problemset/problem/827/C) 4 | -------------------------------------------------------------------------------- /codeforces/exam-cheating/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++14 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /codeforces/exam-cheating/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://codeforces.com/problemset/problem/796/E](http://codeforces.com/problemset/problem/796/E) 4 | 5 | -------------------------------------------------------------------------------- /codeforces/fedor-and-coupons/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++14 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /codeforces/fedor-and-coupons/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://codeforces.com/problemset/problem/754/D](http://codeforces.com/problemset/problem/754/D) 4 | 5 | -------------------------------------------------------------------------------- /codeforces/geometric-progression/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++14 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /codeforces/geometric-progression/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://codeforces.com/problemset/problem/758/F](http://codeforces.com/problemset/problem/758/F) 4 | 5 | -------------------------------------------------------------------------------- /codeforces/innokenty-and-a-football-league/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++14 -Wall -o out 3 | 4 | default: out run 5 | 6 | out: main.cpp 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /codeforces/innokenty-and-a-football-league/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://codeforces.com/problemset/problem/780/D](http://codeforces.com/problemset/problem/780/D) 4 | 5 | -------------------------------------------------------------------------------- /codeforces/interactive-bulls-and-cows-easy/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /codeforces/interactive-bulls-and-cows-easy/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://codeforces.com/problemset/problem/753/B](http://codeforces.com/problemset/problem/753/B) 4 | 5 | -------------------------------------------------------------------------------- /codeforces/interactive-bulls-and-cows-hard/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /codeforces/interactive-bulls-and-cows-hard/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://codeforces.com/problemset/problem/753/C](http://codeforces.com/problemset/problem/753/C) 4 | 5 | -------------------------------------------------------------------------------- /codeforces/karen-and-supermarket/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++14 -Wall -o out 3 | 4 | default: out run 5 | 6 | out: main.cpp 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /codeforces/karen-and-supermarket/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://codeforces.com/problemset/problem/815/C](http://codeforces.com/problemset/problem/815/C) 4 | -------------------------------------------------------------------------------- /codeforces/leaving-auction/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++14 -Wall -o out 3 | 4 | default: out run 5 | 6 | out: main.cpp 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /codeforces/leaving-auction/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://codeforces.com/problemset/problem/749/D](http://codeforces.com/problemset/problem/749/D) 4 | 5 | -------------------------------------------------------------------------------- /codeforces/little-girl-and-maximum-sum/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++14 -Wall -o out 3 | 4 | default: out run 5 | 6 | out: main.cpp 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /codeforces/little-girl-and-maximum-sum/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://codeforces.com/contest/276/problem/C](http://codeforces.com/contest/276/problem/C) 4 | -------------------------------------------------------------------------------- /codeforces/little-girl-and-maximum-sum/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; // NOLINT 4 | 5 | constexpr int MAX_N = 200010; 6 | 7 | // Original sequence. 8 | int A[MAX_N]; 9 | 10 | // Sum D[0...i] is the number of times number i appears in a query. 11 | int64_t D[MAX_N]; 12 | 13 | int main() { 14 | ios::sync_with_stdio(false); 15 | 16 | int n, q; 17 | cin >> n >> q; 18 | 19 | for (int i = 0; i < n; i++) { 20 | cin >> A[i]; 21 | } 22 | 23 | for (int i = 0; i < q; i++) { 24 | int l, r; 25 | cin >> l >> r; 26 | D[l]++; 27 | D[r + 1]--; 28 | } 29 | 30 | // Reduce D. (See comment at top) 31 | for (int i = 1; i <= n; i++) { 32 | D[i] = D[i - 1] + D[i]; 33 | } 34 | 35 | // Place the largest numbers in positions that most commonly occur in queries. 36 | sort(A, A + n); 37 | sort(D + 1, D + n + 1); 38 | 39 | int64_t sum = 0; 40 | 41 | for (int i = 0; i < n; i++) { 42 | sum += A[i] * D[i + 1]; 43 | } 44 | 45 | cout << sum << endl; 46 | 47 | return 0; 48 | } 49 | 50 | -------------------------------------------------------------------------------- /codeforces/mike-and-feet/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++14 -Wall -o out 3 | 4 | default: out run 5 | 6 | out: main.cpp 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /codeforces/mike-and-feet/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://codeforces.com/problemset/problem/547/B](http://codeforces.com/problemset/problem/547/B) 4 | -------------------------------------------------------------------------------- /codeforces/mister-b-and-flight-to-the-moon/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://codeforces.com/problemset/problem/819/E](http://codeforces.com/problemset/problem/819/E) 4 | -------------------------------------------------------------------------------- /codeforces/mister-b-and-pr-shifts/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++14 -Wall -o out 3 | 4 | default: out run 5 | 6 | out: main.cpp 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /codeforces/mister-b-and-pr-shifts/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://codeforces.com/problemset/problem/819/B](http://codeforces.com/problemset/problem/819/B) 4 | -------------------------------------------------------------------------------- /codeforces/multicolored-cars/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://codeforces.com/problemset/problem/818/D](http://codeforces.com/problemset/problem/818/D) 4 | 5 | -------------------------------------------------------------------------------- /codeforces/multicolored-cars/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from collections import defaultdict 4 | 5 | 6 | MAX_N = 10 ** 6 + 1 7 | 8 | 9 | def main(): 10 | n, a = ints() 11 | colors = list(ints()) 12 | 13 | # Count of each color 14 | counts = [0] * MAX_N 15 | 16 | # Map from count -> {Set of colors with this count...} 17 | index = defaultdict(set) 18 | index[0] = set(colors) 19 | 20 | for c in colors: 21 | k = counts[c] 22 | 23 | # Check if color c is... 24 | # (1) previously eliminated 25 | # (2) loses in this iteration which is the first encounter 26 | if k == -1 or k < counts[a]: 27 | continue 28 | 29 | # Update the count of color c 30 | counts[c] = k + 1 31 | index[k].remove(c) 32 | index[k + 1].add(c) 33 | 34 | if c == a: 35 | for x in index[k]: 36 | counts[x] = -1 37 | del index[k] 38 | else: 39 | assert counts[c] >= counts[a] 40 | 41 | sols = [c for c in range(MAX_N) if counts[c] > 0 and c != a] 42 | 43 | if len(sols) > 0: 44 | check(colors, a, sols[0]) 45 | print(sols[0]) 46 | else: 47 | print(-1) 48 | 49 | 50 | def check(colors, a, b): 51 | """Checks that Bob wins with color b if Alice chooses color a.""" 52 | x, y = 0, 0 53 | 54 | for c in colors: 55 | if c == a: 56 | x += 1 57 | elif c == b: 58 | y += 1 59 | assert x <= y, '%d is not a valid solution!' % b 60 | 61 | 62 | def ints(): 63 | """Returns a generator of integers from the next input line.""" 64 | return (int(i) for i in input().split()) 65 | 66 | if __name__ == '__main__': 67 | main() 68 | -------------------------------------------------------------------------------- /codeforces/new-year-and-fireworks/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /codeforces/new-year-and-fireworks/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://codeforces.com/problemset/problem/750/D](http://codeforces.com/problemset/problem/750/D) 4 | 5 | -------------------------------------------------------------------------------- /codeforces/paths-in-complete-binary-tree/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++14 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /codeforces/paths-in-complete-binary-tree/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://codeforces.com/problemset/problem/792/D](http://codeforces.com/problemset/problem/792/D) 4 | 5 | -------------------------------------------------------------------------------- /codeforces/police-stations/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++14 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /codeforces/police-stations/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://codeforces.com/problemset/problem/796/D](http://codeforces.com/problemset/problem/796/D) 4 | 5 | -------------------------------------------------------------------------------- /codeforces/running-with-obstacles/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++14 -Wall -o out 3 | 4 | default: out run 5 | 6 | out: main.cpp 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /codeforces/running-with-obstacles/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://codeforces.com/problemset/problem/637/D](http://codeforces.com/problemset/problem/637/D) 4 | 5 | -------------------------------------------------------------------------------- /codeforces/running-with-obstacles/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; // NOLINT 4 | 5 | constexpr int MAX_N = 200000; 6 | 7 | int N, M, S, D; 8 | 9 | int X[MAX_N + 10]; 10 | 11 | /** 12 | * Each DP[i] indicates if it is possible to reach position M after jumping to 13 | * the spot immediately after obstacle i. 0 => Unknown, 1 => Possible, 14 | * 2 => NOT possible. 15 | */ 16 | int DP[MAX_N + 1] = { 0 }; 17 | 18 | stack OPS; 19 | 20 | void run(int x) { 21 | if (x == 0) return; 22 | 23 | std::ostringstream os; 24 | os << "RUN " << x; 25 | OPS.push(os.str()); 26 | } 27 | 28 | void jump(int x) { 29 | assert(x > 0); 30 | 31 | std::ostringstream os; 32 | os << "JUMP " << x; 33 | OPS.push(os.str()); 34 | } 35 | 36 | bool dfs(int p) { 37 | assert(p >= 0 && p <= N); 38 | 39 | if (DP[p] != 0) { 40 | // We should not be calling again for a p that previous returned true since 41 | // true should propagate all the way back up. 42 | assert(DP[p] == 2); 43 | return false; 44 | } 45 | 46 | if (M < X[p]) { 47 | // Whoa, overshoot! 48 | DP[p] = 2; 49 | return false; 50 | } 51 | 52 | if (p == N || M < X[p + 1]) { 53 | // Cool, target is between last and next obstacle so run directly to it. 54 | run(M - X[p] - 1); 55 | DP[p] = 1; 56 | } else { 57 | DP[p] = 2; 58 | 59 | // Check if there is space for a minimal runup of at least length S. 60 | int space = X[p + 1] - X[p] - 2; 61 | if (space < S) { 62 | return false; 63 | } 64 | 65 | int i = p + 1; 66 | 67 | // Search by jumping over all possible obstacles from current runup. 68 | while (DP[p] != 1 && i <= N && X[i] + 1 <= X[p + 1] - 1 + D) { 69 | if (dfs(i)) { 70 | DP[p] = 1; 71 | jump(X[i] + 1 - X[p + 1] + 1); 72 | run(space); 73 | } 74 | i++; 75 | } 76 | } 77 | 78 | return DP[p] == 1; 79 | } 80 | 81 | int main() { 82 | cin >> N >> M >> S >> D; 83 | 84 | X[0] = -1; 85 | for (int i = 0; i < N; i++) { 86 | cin >> X[i + 1]; 87 | } 88 | sort(&X[0], &X[N + 1]); 89 | 90 | if (!dfs(0)) { 91 | printf("IMPOSSIBLE\n"); 92 | } else { 93 | while (!OPS.empty()) { 94 | cout << OPS.top() << endl; 95 | OPS.pop(); 96 | } 97 | } 98 | 99 | return 0; 100 | } 101 | 102 | -------------------------------------------------------------------------------- /codeforces/template/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++14 -Wall -o out 3 | 4 | default: out run 5 | 6 | out: main.cpp 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /codeforces/template/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | This is a C++14 template for Codeforces. 4 | 5 | -------------------------------------------------------------------------------- /codeforces/template/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; // NOLINT 4 | 5 | int main() { 6 | ios::sync_with_stdio(false); 7 | return 0; 8 | } 9 | 10 | -------------------------------------------------------------------------------- /codeforces/the-bakery/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++14 -Wall -o out 3 | 4 | default: out run 5 | 6 | out: main.cpp 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /codeforces/the-bakery/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://codeforces.com/problemset/problem/833/B](http://codeforces.com/problemset/problem/833/B) 4 | -------------------------------------------------------------------------------- /codeforces/the-penguins-game/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++14 -Wall -o out 3 | 4 | default: out run 5 | 6 | out: main.cpp 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /codeforces/the-penguins-game/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://codeforces.com/problemset/problem/835/E](http://codeforces.com/problemset/problem/835/E) 4 | -------------------------------------------------------------------------------- /codeforces/towers/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++14 -Wall -o out 3 | 4 | default: out run 5 | 6 | out: main.cpp 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /codeforces/towers/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://codeforces.com/problemset/problem/229/D](http://codeforces.com/problemset/problem/229/D) 4 | 5 | -------------------------------------------------------------------------------- /codeforces/underground-lab/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++14 -Wall -o out 3 | 4 | default: out run 5 | 6 | out: main.cpp 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /codeforces/underground-lab/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://codeforces.com/problemset/problem/780/E](http://codeforces.com/problemset/problem/780/E) 4 | 5 | -------------------------------------------------------------------------------- /codeforces/underground-lab/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; // NOLINT 4 | 5 | // 6 | // Runs DFS to create a Euler Tour of the graph G starting at vertex u. 7 | // 8 | void dfs(const vector>& graph, // Graph as an adjacency list 9 | vector& visited, // Visited vertices 10 | vector& tour, // Ordered list of visited vertices 11 | int u) { // Vertex where to start DFS 12 | assert(!visited[u]); 13 | 14 | visited[u] = true; 15 | tour.push_back(u); 16 | 17 | for (int v : graph[u]) { 18 | if (!visited[v]) { 19 | dfs(graph, visited, tour, v); 20 | // Come back to parent before visiting an adjacent sibling of v or 21 | // parent of u! 22 | tour.push_back(u); 23 | } 24 | } 25 | } 26 | 27 | int main() { 28 | int n, m, k, x, y; 29 | cin >> n >> m >> k; 30 | 31 | // Load graph into adjacency list 32 | vector> graph(n); 33 | for (int i = 0; i < m; i++) { 34 | cin >> x >> y; 35 | x--; y--; 36 | graph[x].push_back(y); 37 | graph[y].push_back(x); 38 | } 39 | 40 | // Create a Euler Tour which will have no more than 2 * n - 1 vertices 41 | vector visited(n, false); 42 | vector tour; 43 | dfs(graph, visited, tour, 0); 44 | 45 | // Calculate the max number of vertices each clone can visit 46 | int range = ((2 * n) % k == 0) ? (2 * n) / k : (2 * n) / k + 1; 47 | int total = tour.size(); 48 | 49 | for (int i = 0; i < k; i++) { 50 | int start = i * range; 51 | if (start >= total) { 52 | // We've already visited all vertices with other clones! 53 | cout << "1 1" << endl; 54 | } else { 55 | // Visit up to the next range vertices via clone i 56 | int end = min(start + range, total); 57 | cout << (end - start); 58 | for (int j = start; j < end; j++) { 59 | cout << " " << tour[j] + 1; 60 | } 61 | cout << endl; 62 | } 63 | } 64 | 65 | return 0; 66 | } 67 | 68 | -------------------------------------------------------------------------------- /codeforces/xenia-and-tree/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++14 -Wall -o out 3 | 4 | default: out run 5 | 6 | out: main.cpp 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /codeforces/xenia-and-tree/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://codeforces.com/contest/342/problem/E](http://codeforces.com/contest/342/problem/E) 4 | 5 | -------------------------------------------------------------------------------- /geeks-for-geeks/dynamic-programming/set-18-partition-problem/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://www.geeksforgeeks.org/dynamic-programming-set-18-partition-problem/](http://www.geeksforgeeks.org/dynamic-programming-set-18-partition-problem/) 4 | -------------------------------------------------------------------------------- /geeks-for-geeks/dynamic-programming/set-18-partition-problem/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | TEST_INPUT = [ 4 | [], 5 | [1], 6 | [1, 2], 7 | [1, 2, 3], 8 | [1, 2, 3, 4], 9 | [1, 2, 3, 4, 5], 10 | [1, 2, 3, 4, 5, 6] 11 | ] 12 | 13 | TEST_OUTPUT = [ 14 | True, 15 | False, 16 | False, 17 | True, 18 | True, 19 | False, 20 | False 21 | ] 22 | 23 | 24 | def subset_sum(nums, hi, sum, dp): 25 | """ 26 | Returns a bool indicating if nums[0:hi + 1] has a subset with the specified 27 | sum. DP[i][j] stores bool indicating if nums[0:i + 1] has a subset with sum 28 | j. 29 | """ 30 | 31 | if hi == 0: 32 | # Check only element. 33 | return nums[0] == sum 34 | elif sum in dp[hi]: 35 | # Return cached result. 36 | return dp[hi][sum] 37 | 38 | # Include the last element in the subset. 39 | has_subset = subset_sum(nums, hi - 1, sum - nums[hi], dp) 40 | if not has_subset: 41 | # Exclude the last element in the subset. 42 | has_subset = subset_sum(nums, hi - 1, sum, dp) 43 | 44 | # Cache result and return. 45 | dp[hi][sum] = has_subset 46 | return has_subset 47 | 48 | 49 | def list_partitionable(nums): 50 | """ 51 | Returns a bool indicating if nums can be partitioned into two lists with 52 | equal sums. 53 | """ 54 | 55 | n = len(nums) 56 | if n == 0: 57 | return True 58 | elif n == 1: 59 | return False 60 | 61 | sum = 0 62 | for i in nums: 63 | sum += i 64 | 65 | # Sum must be even so that each subset has sum of sum / 2. 66 | if sum % 2 != 0: 67 | return False 68 | 69 | # DP[i][j] stores bool indicating if nums[0:i + 1] has a subset with sum j. 70 | dp = [dict() for i in range(0, n)] 71 | return subset_sum(nums, n - 1, sum / 2, dp) 72 | 73 | 74 | def main(): 75 | for i in range(0, len(TEST_INPUT)): 76 | print("Running test case %d..." % (i + 1)) 77 | assert TEST_OUTPUT[i] == list_partitionable(TEST_INPUT[i]) 78 | 79 | print("Tests pass!") 80 | 81 | 82 | if __name__ == "__main__": 83 | main() 84 | -------------------------------------------------------------------------------- /geeks-for-geeks/linked-lists/flatten-multi-level-list/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://www.geeksforgeeks.org/flatten-a-linked-list-with-next-and-child-pointers/](http://www.geeksforgeeks.org/flatten-a-linked-list-with-next-and-child-pointers/) 4 | 5 | -------------------------------------------------------------------------------- /geeks-for-geeks/mathematics/weighted-random-generator/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [http://www.geeksforgeeks.org/random-number-generator-in-arbitrary-probability-distribution-fashion/](http://www.geeksforgeeks.org/random-number-generator-in-arbitrary-probability-distribution-fashion/) 4 | 5 | -------------------------------------------------------------------------------- /geeks-for-geeks/mathematics/weighted-random-generator/generators_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from generators import SegmentTreeGenerator, ArrayGenerator, DictGenerator 4 | 5 | SAMPLES = 250000 6 | 7 | INIT_DATA = {'a': 1, 'b': 2, 'c': 3, 'd': 4} 8 | UPDATE_DATA = {'a': 2, 'b': 1, 'c': 3, 'd': 10} 9 | 10 | UPDATES = [('a', 2), ('b', 1), ('d', 10)] 11 | 12 | GENERATORS = [ 13 | SegmentTreeGenerator, 14 | ArrayGenerator, 15 | DictGenerator 16 | ] 17 | 18 | 19 | def test(generator, data): 20 | # Collect data over samples. 21 | results = {value: 0 for value in data.keys()} 22 | for _ in range(0, SAMPLES): 23 | value = generator.random() 24 | results[value] += 1 25 | 26 | # Normalize result frequencies. 27 | for value in results: 28 | results[value] /= float(SAMPLES) 29 | 30 | # Check that the distribution is roughly proportional to the frequency. We 31 | # could use a T-test here to be more mathematicaly precise with our test. 32 | total = sum(data.values()) 33 | expect = {value: data[value] / total for value in data.keys()} 34 | for value in expect: 35 | assert abs(results[value] - expect[value]) < 0.01 36 | 37 | 38 | def main(): 39 | for generator_class in GENERATORS: 40 | print('Testing %s...' % generator_class.__name__) 41 | 42 | # Test the generator with the initial distribution. 43 | generator = generator_class(INIT_DATA) 44 | test(generator, INIT_DATA) 45 | 46 | # Update weights and re-test the distribution of random values. 47 | for (value, weight) in UPDATES: 48 | generator.update(value, weight) 49 | test(generator, UPDATE_DATA) 50 | print('All tests pass!') 51 | 52 | 53 | if __name__ == '__main__': 54 | main() 55 | -------------------------------------------------------------------------------- /geeks-for-geeks/mathematics/weighted-random-generator/range_map_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from range_map import RangeMap 4 | 5 | 6 | DATA = [ 7 | [('a', 1), ('b', 2), ('c', 3)] 8 | ] 9 | 10 | # 11 | # Test cases for interval queries in the range map. Each value is a tuple 12 | # (point, expect) where the test performs a query on the specified point and 13 | # ensures the expected value is returned. 14 | # 15 | QUERIES = [ 16 | [ 17 | (-0.1, None), 18 | (0.5, 'a'), 19 | (1, 'b'), 20 | (2.1, 'b'), 21 | (2.999, 'b'), 22 | (3.5, 'c'), 23 | (6.1, None)] 24 | ] 25 | 26 | # 27 | # Test cases for updating value intervals in the range map. Each value is a 28 | # tuple (value, interval, point, expect) where the test updates the interval 29 | # for the specified value, and performs a point query ensuring the expected 30 | # value is returned. 31 | # 32 | UPDATES = [ 33 | [('a', 2, 1, 'a'), ('a', 0.5, 0.75, 'b'), ('b', 0, 1, 'c')] 34 | ] 35 | 36 | 37 | def test(test_case): 38 | rm = RangeMap(DATA[test_case]) 39 | 40 | print('Testing query...') 41 | for (point, expect) in QUERIES[test_case]: 42 | assert expect == rm.get(point) 43 | 44 | print('Testing updates...') 45 | for (value, interval, point, expect) in UPDATES[test_case]: 46 | rm.update(value, interval) 47 | assert expect == rm.get(point) 48 | 49 | print('Test case %d passes!' % (test_case + 1)) 50 | 51 | 52 | def main(): 53 | for test_case in range(0, len(DATA)): 54 | test(test_case) 55 | print('All tests pass!') 56 | 57 | 58 | if __name__ == '__main__': 59 | main() 60 | -------------------------------------------------------------------------------- /geeks-for-geeks/mathematics/weighted-random-generator/test.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | BASEDIR=$(dirname "$0") 4 | 5 | echo "Testing RangeMap..." 6 | python3 ${BASEDIR}/range_map_test.py 7 | 8 | echo "Testing generators..." 9 | python3 ${BASEDIR}/generators_test.py 10 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/bit-manipulation/and-product/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/bit-manipulation/and-product/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/and-product](https://www.hackerrank.com/challenges/and-product) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/bit-manipulation/and-product/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef uint32_t ultype; 5 | 6 | ultype product(ultype A, ultype B) { 7 | ultype floor_p2 = log2(A), ceil_p2 = log2(B); 8 | if (ceil_p2 >= floor_p2 + 1) { 9 | return 0; 10 | } 11 | ultype product = A; 12 | while (A < B) { 13 | A++; 14 | product = product & A; 15 | } 16 | return product; 17 | } 18 | 19 | int main() { 20 | ultype A, B, T; 21 | std::cin >> T; 22 | while (T--) { 23 | std::cin >> A >> B; 24 | std::cout << product(A, B) << std::endl; 25 | } 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/bit-manipulation/cipher/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/bit-manipulation/cipher/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/cipher](https://www.hackerrank.com/challenges/cipher) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/bit-manipulation/cipher/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | std::vector decode(const std::vector& message, int N, int K) { 6 | bool last_k_xor = message[0]; 7 | std::vector decoded(N, 0); 8 | decoded[0] = message[0]; 9 | for (int i = 1; i < N; ++i) { 10 | if (i >= K) { 11 | last_k_xor = last_k_xor ^ decoded[i - K]; 12 | } 13 | decoded[i] = last_k_xor ^ message[i]; 14 | last_k_xor = last_k_xor ^ decoded[i]; 15 | } 16 | return decoded; 17 | } 18 | 19 | int main() { 20 | int N, K; 21 | std::cin >> N >> K; 22 | 23 | int length = N + K - 1; 24 | std::vector message(length); 25 | char c; 26 | for (size_t i = 0; i < message.size(); ++i) { 27 | std::cin >> c; 28 | message[i] = c - '0'; 29 | } 30 | 31 | std::vector decoded = decode(message, N, K); 32 | std::ostream_iterator out(std::cout); 33 | std::copy(decoded.begin(), decoded.end(), out); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/bit-manipulation/flipping-bits/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/bit-manipulation/flipping-bits/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/flipping-bits](https://www.hackerrank.com/challenges/flipping-bits) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/bit-manipulation/flipping-bits/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | uint32_t T, i; 5 | std::cin >> T; 6 | while (T-- > 0) { 7 | std::cin >> i; 8 | std::cout << ~i << std::endl; 9 | } 10 | return 0; 11 | } 12 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/dynamic-programming/candies/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/candies](https://www.hackerrank.com/challenges/candies) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/dynamic-programming/candies/candies.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | 5 | 6 | def candies(children): 7 | length = len(children) 8 | 9 | if (length <= 1): 10 | return length 11 | 12 | candies = [1] * length 13 | 14 | # Perform left to right rankings 15 | for i in range(1, length): 16 | if (children[i] > children[i - 1]): 17 | candies[i] = candies[i - 1] + 1 18 | 19 | # Tracks number of candies 20 | count = candies[length - 1] 21 | 22 | # Perform right to left rankings 23 | for i in range(length - 1, 0, -1): 24 | if (children[i - 1] > children[i]): 25 | candies[i - 1] = max(candies[i - 1], candies[i] + 1) 26 | count += candies[i - 1] 27 | 28 | return count 29 | 30 | 31 | def main(): 32 | n = int(sys.stdin.readline()) 33 | children = [0] * n 34 | for i in range(0, n): 35 | children[i] = int(sys.stdin.readline()) 36 | print(candies(children)) 37 | 38 | 39 | if __name__ == '__main__': 40 | main() 41 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/dynamic-programming/coin-change/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/coin-change](https://www.hackerrank.com/challenges/coin-change) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/dynamic-programming/coin-change/coin-change.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | 5 | 6 | def read_ints(): 7 | line = sys.stdin.readline().strip() 8 | return [int(x) for x in line.split(" ")] 9 | 10 | 11 | def change(cents, denom, coins, cache): 12 | # The value in cents of the current coint we are using for change. 13 | coin = coins[denom] 14 | 15 | # If this is the last coin check if it can divide the remaining cents. 16 | if (denom == (len(coins) - 1)): 17 | return int((cents % coin) == 0) 18 | 19 | # Check if we have calculated this cents/coin combo before. 20 | if (denom in cache and cents in cache[denom]): 21 | return cache[denom][cents] 22 | 23 | # Calculate the number of ways to give change using increasing quantities 24 | # of this coin. 25 | ways = 0 26 | nextDenom = denom + 1 27 | currentCents = cents 28 | while (currentCents >= 0): 29 | ways += change(currentCents, nextDenom, coins, cache) 30 | currentCents -= coin 31 | 32 | # Store result to cache. 33 | if (denom not in cache): 34 | cache[denom] = {} 35 | cache[denom][cents] = ways 36 | 37 | return ways 38 | 39 | 40 | def main(): 41 | (N, M) = read_ints() 42 | coins = read_ints() 43 | print(change(N, 0, coins, {})) 44 | 45 | 46 | if __name__ == '__main__': 47 | main() 48 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/dynamic-programming/fibonacci-modified/Makefile: -------------------------------------------------------------------------------- 1 | default: build run 2 | 3 | build: 4 | javac Solution.java 5 | 6 | run: 7 | java Solution 8 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/dynamic-programming/fibonacci-modified/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/fibonacci-modified](https://www.hackerrank.com/challenges/fibonacci-modified) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/dynamic-programming/fibonacci-modified/Solution.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.InputStreamReader; 3 | import java.io.IOException; 4 | import java.math.BigInteger; 5 | 6 | public class Solution { 7 | public static void main(String[] args) { 8 | BufferedReader bi = new BufferedReader(new InputStreamReader(System.in)); 9 | String[] tokens = null; 10 | try { 11 | tokens = bi.readLine().split("\\s"); 12 | } catch (IOException e) { 13 | System.err.println(e); 14 | System.exit(1); 15 | } 16 | BigInteger b = new BigInteger(tokens[0]); 17 | BigInteger a = new BigInteger(tokens[1]); 18 | int n = Integer.parseInt(tokens[2]) - 2; 19 | 20 | BigInteger tmp = null; 21 | while (n > 0) { 22 | tmp = a; 23 | a = a.multiply(a).add(b); 24 | b = tmp; 25 | --n; 26 | } 27 | 28 | System.out.println(a); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/dynamic-programming/grid-walking/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/dynamic-programming/grid-walking/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/grid-walking](https://www.hackerrank.com/challenges/grid-walking) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/dynamic-programming/longest-common-subsequence/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/dynamic-programming/longest-common-subsequence/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/dynamic-programming-classics-the-longest-common-subsequence](https://www.hackerrank.com/challenges/dynamic-programming-classics-the-longest-common-subsequence) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/dynamic-programming/longest-increasing-subsequence/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/dynamic-programming/longest-increasing-subsequence/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/longest-increasing-subsequent](https://www.hackerrank.com/challenges/longest-increasing-subsequent) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/dynamic-programming/longest-increasing-subsequence/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | std::vector build(int length) { 5 | std::vector sequence(length); 6 | for (size_t i = 0; i < length; ++i) { 7 | std::cin >> sequence[i]; 8 | } 9 | return sequence; 10 | } 11 | 12 | // Returns index of ceil of value in tails. (i.e. the smallest element greater 13 | // than value) 14 | int searchceil(const std::vector& tails, size_t last, int value) { 15 | size_t left = 0, right = last; 16 | while (right > left + 1) { 17 | size_t mid = (left + right)/2; // Works because tails.size() <= 10^6. 18 | if (tails[mid] >= value) { 19 | right = mid; 20 | } else { 21 | left = mid; 22 | } 23 | } 24 | return right; 25 | } 26 | 27 | int lis(const std::vector& sequence) { 28 | std::vector tails(sequence.size()); 29 | tails[0] = sequence[0]; 30 | size_t last = 0; 31 | for (size_t i = 1; i < sequence.size(); i++) { 32 | if (sequence[i] <= tails[0]) { 33 | tails[0] = sequence[i]; 34 | } else if (sequence[i] > tails[last]) { 35 | tails[++last] = sequence[i]; 36 | } else { 37 | size_t existing_index = searchceil(tails, last, sequence[i]); 38 | tails[existing_index] = sequence[i]; 39 | } 40 | } 41 | return last + 1; 42 | } 43 | 44 | int main() { 45 | int N; 46 | std::cin >> N; 47 | std::vector sequence = build(N); 48 | std::cout << lis(sequence); 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/dynamic-programming/maximum-subarray/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/dynamic-programming/maximum-subarray/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/maxsubarray](https://www.hackerrank.com/challenges/maxsubarray) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/dynamic-programming/maximum-subarray/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | std::vector build(int N) { 6 | std::vector array(N); 7 | for (size_t i = 0; i < array.size(); ++i) { 8 | std::cin >> array[i]; 9 | } 10 | return array; 11 | } 12 | 13 | template 14 | T kadane(const std::vector& array) { 15 | T all = array[0], here = array[0]; 16 | for (size_t i = 1; i < array.size(); ++i) { 17 | here = std::max(array[i], here + array[i]); 18 | all = std::max(all, here); 19 | } 20 | return all; 21 | } 22 | 23 | template 24 | T max_noncontig_sum(const std::vector& array) { 25 | T max = std::numeric_limits::min(); 26 | T current = 0; 27 | for (size_t i = 0; i < array.size(); ++i) { 28 | current = array[i]; 29 | if (max < 0 && current < 0) { 30 | max = std::max(max, current); 31 | continue; 32 | } 33 | max = std::max(0, max); 34 | max += std::max(0, current); 35 | } 36 | return max; 37 | } 38 | 39 | void test() { 40 | size_t N = 0; 41 | std::cin >> N; 42 | std::cin.ignore(); 43 | std::vector array = build(N); 44 | int cont = kadane(array); 45 | int non_cont = max_noncontig_sum(array); 46 | std::cout << cont << " " << non_cont << std::endl; 47 | } 48 | 49 | int main() { 50 | int T = 0; 51 | std::cin >> T; 52 | while (T--) { 53 | test(); 54 | } 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/dynamic-programming/square-subsequences/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/dynamic-programming/square-subsequences/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/square-subsequences](https://www.hackerrank.com/challenges/square-subsequences) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/dynamic-programming/stock-maximize/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/dynamic-programming/stock-maximize/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/stockmax](https://www.hackerrank.com/challenges/stockmax) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/dynamic-programming/stock-maximize/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | // 7 | // Calculate the maximum trading profit possible given a price history. 8 | // 9 | uint64_t maxProfit(const std::vector& prices) { 10 | // No profit possible with less than 2 trading days... 11 | if (prices.size() < 2) { 12 | return 0; 13 | } 14 | uint64_t profit = 0; 15 | // Highest price in first i + 1 prices... 16 | uint32_t high = prices[prices.size() - 1]; 17 | // Go through prices in reverse... 18 | for (int i = prices.size() - 2; i >= 0; i--) { 19 | if (prices[i] > high) { 20 | high = prices[i]; 21 | } 22 | // The potential profit from a purchase today... 23 | profit += high - prices[i]; 24 | } 25 | return profit; 26 | } 27 | 28 | // 29 | // Read N stock prices into a vector of size N. 30 | // 31 | std::vector loadPrices(std::istream& in, size_t N) { // NOLINT 32 | std::vector prices; 33 | std::copy_n(std::istream_iterator(std::cin), 34 | N, 35 | std::back_inserter(prices)); 36 | return prices; 37 | } 38 | 39 | int main() { 40 | size_t T, N; 41 | std::cin >> T; 42 | while (T--) { 43 | std::cin >> N; 44 | std::vector prices = loadPrices(std::cin, N); 45 | std::cout << maxProfit(prices) << std::endl; 46 | } 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/dynamic-programming/summing-pieces/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/summing-pieces](https://www.hackerrank.com/challenges/summing-pieces) 4 | 5 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/graph-theory/bfs-shortest-reach/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/bfsshortreach](https://www.hackerrank.com/challenges/bfsshortreach) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/graph-theory/bfs-shortest-reach/bfs-shortest-reach.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | from queue import Queue 5 | 6 | 7 | def read_ints(): 8 | return [int(x) for x in sys.stdin.readline().split(" ")] 9 | 10 | 11 | def build_graph(N, M): 12 | node_edges = [0] 13 | while (N > 0): 14 | node_edges.append([]) 15 | N -= 1 16 | while (M > 0): 17 | (x, y) = read_ints() 18 | node_edges[x].append(y) 19 | node_edges[y].append(x) 20 | M -= 1 21 | return node_edges 22 | 23 | 24 | def compute_distances(S, node_edges): 25 | distances = {S: 0} 26 | queue = Queue() 27 | queue.put(S) 28 | while (not queue.empty()): 29 | element = queue.get() 30 | distance = distances[element] + 6 31 | for neighbor in node_edges[element]: 32 | if (neighbor in distances): 33 | continue 34 | distances[neighbor] = distance 35 | queue.put(neighbor) 36 | return distances 37 | 38 | 39 | def print_distances(S, N, distances): 40 | for i in range(1, N + 1): 41 | if (i == S): 42 | continue 43 | if i in distances: 44 | print(distances[i], end=" "), 45 | else: 46 | print(-1, end=" "), 47 | print() 48 | 49 | 50 | def test_case(): 51 | (N, M) = read_ints() 52 | node_edges = build_graph(N, M) 53 | S = int(sys.stdin.readline()) 54 | distances = compute_distances(S, node_edges) 55 | print_distances(S, N, distances) 56 | 57 | 58 | def main(): 59 | T = int(sys.stdin.readline()) 60 | while (T > 0): 61 | test_case() 62 | T -= 1 63 | 64 | if __name__ == '__main__': 65 | main() 66 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/graph-theory/crab-graphs/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++14 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/graph-theory/crab-graphs/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/crab-graphs](https://www.hackerrank.com/challenges/crab-graphs) 4 | 5 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/graph-theory/dijkstra-shortest-reach-2/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/dijkstrashortreach](https://www.hackerrank.com/challenges/dijkstrashortreach) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/graph-theory/dijkstra-shortest-reach-2/dijkstra-shortest-reach-2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | from heapq import * 5 | 6 | 7 | def read(fn): 8 | return tuple(fn(i) for i in sys.stdin.readline().split(' ')) 9 | 10 | 11 | def load_graph(N, M): 12 | """ 13 | Builds an adjacency list representation of a graph with N vertices. Each 14 | graph[i][j] is the minimum length of an edge between vertice i and j. 15 | 16 | :rtype List[int, Dict[int, int]] 17 | """ 18 | graph = [dict() for i in range(0, N)] 19 | 20 | for i in range(0, M): 21 | (x, y, r) = read(int) 22 | x -= 1 23 | y -= 1 24 | 25 | # Ignore all edges except minimum length edge. 26 | r = r if y not in graph[x] else min(r, graph[x][y]) 27 | graph[x][y] = r 28 | graph[y][x] = r 29 | 30 | return graph 31 | 32 | 33 | def dijkstras(graph, source): 34 | """ 35 | Runs Dijkstras on the graph starting at the source vertex. Returns a list 36 | of distances from the source to all other nodes. Distance of -1 for a 37 | vertex i indicates there is no path from source to i. 38 | 39 | :rtype List[int] 40 | """ 41 | q = [] 42 | heappush(q, (0, source)) 43 | 44 | distances = [-1] * len(graph) 45 | distances[source] = 0 46 | 47 | while len(q) > 0: 48 | (distance, vertice) = heappop(q) 49 | 50 | # Ignore this distance if a shorter path has been found for this node. 51 | if distances[vertice] > 0: 52 | continue 53 | distances[vertice] = distance 54 | 55 | # Queue up all unvisited neighbors. 56 | for n in graph[vertice]: 57 | if distances[n] > -1: 58 | continue 59 | cost = distance + graph[vertice][n] 60 | heappush(q, (cost, n)) 61 | 62 | return distances 63 | 64 | 65 | def test(): 66 | (N, M) = read(int) 67 | graph = load_graph(N, M) 68 | 69 | S = read(int)[0] - 1 70 | distances = dijkstras(graph, S) 71 | 72 | for i in range(0, N): 73 | if i != S: 74 | end = ' ' if i < N - 1 else '\n' 75 | print(distances[i], end=end) 76 | 77 | 78 | def main(): 79 | T = read(int)[0] 80 | for i in range(0, T): 81 | test() 82 | 83 | if __name__ == '__main__': 84 | main() 85 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/graph-theory/floyd-city-of-blinding-lights/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/graph-theory/floyd-city-of-blinding-lights/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/floyd-city-of-blinding-lights](https://www.hackerrank.com/challenges/floyd-city-of-blinding-lights) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/graph-theory/floyd-city-of-blinding-lights/floyd_warshall.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | from heapq import * 5 | 6 | 7 | def read(fn): 8 | return tuple(fn(i) for i in sys.stdin.readline().split(' ')) 9 | 10 | 11 | def load_graph(N, M): 12 | """ 13 | Builds an adjacency matrix representation of a graph with N vertices. Each 14 | graph[i][j] is the length of an edge between vertice i and j. Lengths of -1 15 | indicate there is no edge between two vertices. 16 | 17 | :rtype: List[List[int]] 18 | """ 19 | graph = [[-1] * N for i in range(0, N)] 20 | 21 | for i in range(0, M): 22 | (x, y, r) = read(int) 23 | x -= 1 24 | y -= 1 25 | graph[x][y] = r 26 | 27 | # Zero out edges to self. 28 | for i in range(0, N): 29 | graph[i][i] = 0 30 | 31 | return graph 32 | 33 | 34 | def floyd_warshall(graph): 35 | """ 36 | Takes an adjacency matrix graph of edge distances and returns a matrix of 37 | shortest distances between all pairs of vertices. Distances of -1 indicate 38 | there is no path between a pair of vertices. 39 | 40 | See: http://www.cs.cornell.edu/~wdtseng/icpc/notes/graph_part3.pdf 41 | 42 | :rtype: List[List[int]] 43 | """ 44 | N = len(graph) 45 | distances = [list(graph[i]) for i in range(0, N)] 46 | 47 | # After the n-th iteration of the loop, each distances[j][k] contains 48 | # length of shortest path from j to k through vertices {0...n - 1} 49 | for i in range(0, N): 50 | for j in range(0, N): 51 | for k in range(0, N): 52 | if distances[j][i] == -1 or distances[i][k] == -1: 53 | continue 54 | # Use vertex i as a mid-point vertex. 55 | candidate = distances[j][i] + distances[i][k] 56 | if distances[j][k] == -1 or candidate < distances[j][k]: 57 | distances[j][k] = candidate 58 | 59 | return distances 60 | 61 | 62 | def main(): 63 | (N, M) = read(int) 64 | 65 | graph = load_graph(N, M) 66 | distances = floyd_warshall(graph) 67 | 68 | Q = read(int)[0] 69 | for i in range(0, Q): 70 | (a, b) = read(int) 71 | a -= 1 72 | b -= 1 73 | print(distances[a][b]) 74 | 75 | 76 | if __name__ == '__main__': 77 | main() 78 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/graph-theory/floyd-city-of-blinding-lights/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | typedef std::vector> matrix; 5 | 6 | // 7 | // Builds an adjacency matrix representation of a graph with N vertices. Each 8 | // graph[i][j] is the length of an edge between vertices i and j. Lengths of -1 9 | // indicate there is no edge between two vertices. 10 | // 11 | matrix build_graph(size_t N, size_t M) { 12 | matrix graph(N, std::vector(N, -1)); 13 | 14 | size_t x, y; 15 | int r; 16 | while (M-- > 0) { 17 | std::cin >> x >> y >> r; 18 | graph[--x][--y] = r; 19 | } 20 | 21 | // Zero out edges to self. 22 | for (size_t i = 0; i < N; i++) { 23 | graph[i][i] = 0; 24 | } 25 | 26 | return graph; 27 | } 28 | 29 | // 30 | // Takes an adjacency matrix graph of distances between vertices and runs Floyd 31 | // Warshall to find the shortest distances between all pairs of vertices. 32 | // Distances of -1 indicate there is no path between a pair of vertices. 33 | // 34 | // See: http://www.cs.cornell.edu/~wdtseng/icpc/notes/graph_part3.pdf 35 | // 36 | void floyd_warshall(matrix& graph, size_t N) { // NOLINT 37 | // After the n-th iteration of the loop, each graph[j][k] contains the length 38 | // of the shortest path from j to k through some or none of vertices 39 | // {0...n - 1}. 40 | for (size_t i = 0; i < N; ++i) { 41 | for (size_t j = 0; j < N; ++j) { 42 | for (size_t k = 0; k < N; ++k) { 43 | // Use vertex i as a mid-point between j and k. Check if there even 44 | // exists a path from j -> i and i -> k. 45 | if (graph[j][i] == -1 || graph[i][k] == -1) { 46 | continue; 47 | } 48 | // Check if path j -> ? -> i -> ? -> k is shorter than j -> ? -> k. 49 | int candidate = graph[j][i] + graph[i][k]; 50 | if (candidate < graph[j][k] || graph[j][k] == -1) { 51 | graph[j][k] = candidate; 52 | } 53 | } 54 | } 55 | } 56 | } 57 | 58 | int main() { 59 | size_t N, M; 60 | std::cin >> N >> M; 61 | matrix graph = build_graph(N, M); 62 | floyd_warshall(graph, N); 63 | 64 | size_t Q; 65 | std::cin >> Q; 66 | while (Q-- > 0) { 67 | int a, b; 68 | std::cin >> a >> b; 69 | std::cout << graph[--a][--b] << std::endl; 70 | } 71 | 72 | return 0; 73 | } 74 | 75 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/graph-theory/jack-goes-to-rapture/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/jack-goes-to-rapture](https://www.hackerrank.com/challenges/jack-goes-to-rapture) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/graph-theory/jack-goes-to-rapture/jack-goes-to-rapture.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | import queue 5 | 6 | 7 | def read_ints(): 8 | return [int(x) for x in sys.stdin.readline().split()] 9 | 10 | 11 | def build_graph(E): 12 | graph = {} 13 | while (E > 0): 14 | (s1, s2, cost) = read_ints() 15 | if s1 not in graph: 16 | graph[s1] = [] 17 | graph[s1].append((s2, cost)) 18 | if s2 not in graph: 19 | graph[s2] = [] 20 | graph[s2].append((s1, cost)) 21 | E -= 1 22 | return graph 23 | 24 | 25 | def next_stations(current, graph, stations_queue, costs_cache): 26 | for (station, cost) in graph[current]: 27 | base_cost = costs_cache[current] 28 | cost = base_cost + max(0, cost - base_cost) 29 | if (station in costs_cache and costs_cache[station] < cost): 30 | continue 31 | stations_queue.put((cost, station)) 32 | 33 | 34 | def calculate(graph, N): 35 | costs_cache = {1: 0} 36 | stations_queue = queue.PriorityQueue() 37 | next_stations(1, graph, stations_queue, costs_cache) 38 | while not stations_queue.empty(): 39 | (cost, current) = stations_queue.get() 40 | if (current == N): 41 | return cost 42 | if (current in costs_cache): 43 | continue 44 | costs_cache[current] = cost 45 | next_stations(current, graph, stations_queue, costs_cache) 46 | 47 | 48 | def main(): 49 | (N, E) = read_ints() 50 | graph = build_graph(E) 51 | result = calculate(graph, N) 52 | if (result is None): 53 | print("NO PATH EXISTS") 54 | else: 55 | print(result) 56 | 57 | if __name__ == "__main__": 58 | main() 59 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/graph-theory/journey-to-the-moon/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/journey-to-the-moon](https://www.hackerrank.com/challenges/journey-to-the-moon) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/graph-theory/journey-to-the-moon/journey-to-the-moon.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | import queue 5 | 6 | 7 | def read_ints(): 8 | return [int(x) for x in sys.stdin.readline().split()] 9 | 10 | 11 | def build_graph(I): 12 | graph = {} 13 | while (I > 0): 14 | (A, B) = read_ints() 15 | if (A not in graph): 16 | graph[A] = [] 17 | if (B not in graph): 18 | graph[B] = [] 19 | graph[A].append(B) 20 | graph[B].append(A) 21 | I -= 1 22 | return graph 23 | 24 | 25 | def traverse(graph, astronaut): 26 | country_size = 0 27 | q = queue.Queue() 28 | q.put(astronaut) 29 | while (not q.empty()): 30 | a = q.get() 31 | if (graph[a] is None): 32 | continue 33 | country_size += 1 34 | edges = graph[a] 35 | graph[a] = None 36 | for b in edges: 37 | q.put(b) 38 | return country_size 39 | 40 | 41 | def combinations(graph, N): 42 | combinations = astronauts = 0 43 | for a in graph: 44 | country_size = traverse(graph, a) 45 | combinations += astronauts * country_size 46 | astronauts += country_size 47 | # Each independent astronaut will add {#astronauts} combinations 48 | combinations += int((astronauts + N - 1) * 0.5 * (N - astronauts)) 49 | return combinations 50 | 51 | 52 | def main(): 53 | (N, I) = read_ints() 54 | graph = build_graph(I) 55 | print(combinations(graph, N)) 56 | 57 | if __name__ == "__main__": 58 | main() 59 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/graph-theory/kruskal-mst-really-special-subtree/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/graph-theory/kruskal-mst-really-special-subtree/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/kruskalmstrsub](https://www.hackerrank.com/challenges/kruskalmstrsub) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/graph-theory/prims-mst-special-subtree/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/graph-theory/prims-mst-special-subtree/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/primsmstsub](https://www.hackerrank.com/challenges/primsmstsub) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/graph-theory/prims-mst-special-subtree/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct edge { 6 | int to; // The vertex this edge is directed at 7 | int cost; 8 | }; 9 | 10 | struct vertex { 11 | std::vector edges; 12 | }; 13 | 14 | struct comparator { 15 | bool operator()(const edge& lhs, const edge& rhs) { 16 | return lhs.cost > rhs.cost; 17 | } 18 | }; 19 | 20 | class subgraph { 21 | private: 22 | typedef std::priority_queue, comparator> edgequeue; 23 | 24 | std::vector visited; 25 | 26 | edgequeue queue; 27 | 28 | void push(const vertex& node) { 29 | for (const edge& edge : node.edges) { 30 | if (this->visited[edge.to]) { 31 | continue; 32 | } 33 | this->queue.push(edge); 34 | } 35 | } 36 | 37 | public: 38 | int calculate(const std::vector& verticies, int S) { 39 | int cost = 0; 40 | this->visited.assign(verticies.size(), false); 41 | 42 | this->queue.emplace(edge {S, 0}); 43 | while (!this->queue.empty()) { 44 | edge current = this->queue.top(); 45 | this->queue.pop(); 46 | if (this->visited[current.to]) { 47 | continue; 48 | } 49 | this->visited[current.to] = true; 50 | cost += current.cost; 51 | this->push(verticies[current.to]); 52 | } 53 | 54 | this->visited.clear(); // Clear visited vertices 55 | this->queue = edgequeue(); // Clear the edge queue 56 | 57 | return cost; 58 | } 59 | }; 60 | 61 | int main() { 62 | int N, M, x, y, r, S; 63 | std::cin >> N >> M; 64 | 65 | std::vector verticies(N + 1); 66 | for (size_t i = 0; i < M; ++i) { 67 | std::cin >> x >> y >> r; 68 | verticies[x].edges.emplace_back(edge {y, r}); 69 | verticies[y].edges.emplace_back(edge {x, r}); 70 | } 71 | 72 | subgraph sub; 73 | 74 | std::cin >> S; 75 | std::cout << sub.calculate(verticies, S) << std::endl; 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/graph-theory/prims-mst-special-subtree/prims-mst.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | from queue import PriorityQueue 5 | 6 | 7 | class Graph(object): 8 | """ 9 | Represents a graph using an adjacency list. 10 | """ 11 | def __init__(self, N): 12 | self.nodes = [None] * N 13 | 14 | def add_undir_edge(self, x, y, r): 15 | self.add_dir_edge(x, y, r) 16 | self.add_dir_edge(y, x, r) 17 | 18 | def add_dir_edge(self, x, y, r): 19 | if self.nodes[x] is None: 20 | self.nodes[x] = dict() 21 | self.nodes[x][y] = r 22 | 23 | 24 | def load_graph(input): 25 | """ 26 | Populates a graph using the input stream. 27 | """ 28 | (N, M) = [int(i) for i in input.readline().split(' ')] 29 | graph = Graph(N) 30 | for i in range(0, M): 31 | (x, y, r) = [int(i) for i in input.readline().split(' ')] 32 | graph.add_undir_edge(x - 1, y - 1, r) 33 | return graph 34 | 35 | 36 | def prims_weight(graph, S): 37 | """ 38 | Runs Prim's algorithm on the graph and returns the weight of the MST. 39 | """ 40 | weight = 0 41 | queue = PriorityQueue() 42 | queue.put((0, S)) 43 | visited = [False] * len(graph.nodes) 44 | while queue.qsize() > 0: 45 | (cost, node) = queue.get() 46 | if visited[node]: 47 | continue 48 | visited[node] = True # Mark node as visited 49 | weight += cost # Increment MST weight 50 | for neighbor in graph.nodes[node]: # Enqueue neighbors 51 | if visited[neighbor]: 52 | continue 53 | cost = graph.nodes[node][neighbor] 54 | queue.put((cost, neighbor)) 55 | return weight 56 | 57 | 58 | def main(): 59 | graph = load_graph(sys.stdin) 60 | S = int(sys.stdin.readline()) 61 | weight = prims_weight(graph, S - 1) 62 | print(weight) 63 | 64 | 65 | if __name__ == '__main__': 66 | main() 67 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/graph-theory/scc/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | This is not a HackerRank challenge but an implementation to find strongly 4 | connected components of a directed graph. 5 | 6 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/implementation/matrix-rotation/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/implementation/matrix-rotation/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/matrix-rotation-algo](https://www.hackerrank.com/challenges/matrix-rotation-algo) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/search/connected-cell-in-a-grid/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/search/connected-cell-in-a-grid/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/connected-cell-in-a-grid](https://www.hackerrank.com/challenges/connected-cell-in-a-grid) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/search/connected-cell-in-a-grid/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | const int16_t DELTA_X[] = {-1, 0, 1, 1, 1, 0, -1, -1}; 5 | const int16_t DELTA_Y[] = {-1, -1, -1, 0, 1, 1, 1, 0}; 6 | 7 | typedef std::vector> matrix; 8 | 9 | matrix load(int m, int n) { 10 | matrix mtx(m, std::vector(n)); 11 | for (int i = 0; i < m; ++i) { 12 | for (int k = 0; k < n; ++k) { 13 | std::cin >> mtx[i][k]; 14 | } 15 | } 16 | return mtx; 17 | } 18 | 19 | int floodfill(matrix& mtx, int row, int col) { // NOLINT 20 | int size = 1; 21 | mtx[row][col] = 0; 22 | for (int i = 0; i < 8; ++i) { 23 | int16_t x = col + DELTA_X[i]; 24 | int16_t y = row + DELTA_Y[i]; 25 | // Check if out of bounds 26 | if (x < 0 || x >= mtx[y].size() || y < 0 || y >= mtx.size()) { 27 | continue; 28 | } 29 | // Out of region or already visited 30 | if (mtx[y][x] == 0) { 31 | continue; 32 | } 33 | size += floodfill(mtx, y, x); 34 | } 35 | return size; 36 | } 37 | 38 | int maxregion(matrix& mtx) { // NOLINT 39 | int largest = 0; 40 | for (int r = 0; r < mtx.size(); ++r) { 41 | for (int c = 0; c < mtx[r].size(); ++c) { 42 | // Skip visited cells 43 | if (mtx[r][c] == 0) { 44 | continue; 45 | } 46 | largest = std::max(largest, floodfill(mtx, r, c)); 47 | } 48 | } 49 | return largest; 50 | } 51 | 52 | int main() { 53 | int m, n; 54 | std::cin >> m >> n; 55 | matrix mtx = load(m, n); 56 | std::cout << maxregion(mtx) << std::endl;; 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/search/cut-the-tree/Makefile: -------------------------------------------------------------------------------- 1 | default: build run 2 | 3 | build: 4 | javac Solution.java 5 | 6 | run: 7 | java Solution 8 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/search/cut-the-tree/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/cut-the-tree](https://www.hackerrank.com/challenges/cut-the-tree) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/search/max-sum-k-non-adjacent/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/search/max-sum-k-non-adjacent/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | This isn't a HackerRank challenge - just something I wanted to try. 4 | 5 | ## Problem 6 | 7 | Find the sum of the top K non-adjacent integers in a list. 8 | 9 | ### Input Format 10 | 11 | The first line contains a single integer T, the number of test cases. For every 12 | test case, the first line contains a single integer N, where N is the size of 13 | the list. The next line contains a single integer K. The following line contains 14 | N integers {a1, a2 ... aN}. 15 | 16 | You can execute `python3 generator.py` to create some random input data. 17 | 18 | ### Constraints 19 | 20 | 0 <= T <= 232 - 1 21 | 22 | 0 <= N <= 232 - 1 23 | 24 | 0 < K <= N 25 | 26 | 0 <= ai <= 232 - 1 27 | 28 | ### Output Format 29 | 30 | For each test case, print the sum of the top K non-adjacent integers of the list 31 | or -1 if it is not possible to pick K non-adjacent integers. 32 | 33 | ### Sample Input 34 | 35 | ``` 36 | 1 37 | 5 38 | 3 39 | 1 2 3 4 5 40 | ``` 41 | 42 | ### Sample Output 43 | 44 | ``` 45 | 9 46 | ``` 47 | 48 | ### Explanation 49 | 50 | 5 + 3 + 1 = 9 51 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/search/max-sum-k-non-adjacent/generator.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import argparse 4 | import random 5 | 6 | VERSION = '1.0.0' 7 | 8 | 9 | def run(args): 10 | print(args.T) 11 | for T in range(0, args.T): 12 | N = random.randint(int(args.N/2), args.N + 1) 13 | print(N) 14 | T = random.randint(1, int(N/50) + 1) 15 | print(T) 16 | for i in range(0, N): 17 | print(random.randint(args.min, args.max), end=" ") 18 | print() 19 | 20 | 21 | def main(): 22 | parser = argparse.ArgumentParser() 23 | parser.add_argument("--version", action="version", version=VERSION) 24 | parser.add_argument("--T", help="Number of test cases", type=int, 25 | default=10) 26 | parser.add_argument("--min", help="The minimum randomly generated a", 27 | type=int, default=0) 28 | parser.add_argument("--max", help="The maximum randomly generated a", 29 | type=int, default=1000) 30 | parser.add_argument("--N", help="Sets N/2 to N + 1 numbers per test case", 31 | type=int, default=1000) 32 | 33 | args = parser.parse_args() 34 | run(args) 35 | 36 | if __name__ == "__main__": 37 | main() 38 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/search/maximise-sum/Makefile: -------------------------------------------------------------------------------- 1 | default: build run 2 | 3 | build: 4 | javac Solution.java 5 | 6 | run: 7 | java Solution 8 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/search/maximise-sum/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/maximise-sum](https://www.hackerrank.com/challenges/maximise-sum) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/search/maximise-sum/Solution.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | import java.util.TreeSet; 3 | 4 | public class Solution { 5 | public static void main(String[] args) { 6 | Scanner scanner = new Scanner(System.in); 7 | int t = Integer.parseInt(scanner.nextLine()); 8 | 9 | for (int i = 0; i < t; i++) { 10 | testCase(scanner); 11 | } 12 | } 13 | 14 | public static void testCase(Scanner scanner) { 15 | // Read in N and M. 16 | int n = scanner.nextInt(); 17 | long m = scanner.nextLong(); 18 | scanner.nextLine(); 19 | 20 | // Keep track of the current and max prefix. 21 | long max = 0; 22 | long prefix = 0; 23 | 24 | // Use a tree to efficiently query previous prefixes 25 | TreeSet treeSet = new TreeSet(); 26 | treeSet.add(prefix); 27 | 28 | for (int i = 0; i < n; i++) { 29 | // Read in next element. 30 | long e = scanner.nextLong(); 31 | 32 | // Calculate the mod-sum of the sub-array 0 to i. 33 | prefix = (prefix + e) % m; 34 | max = Math.max(max, prefix); 35 | 36 | // Check for the lowest prefix greater than this one. 37 | Long start = treeSet.higher(prefix); 38 | if (start != null) { 39 | max = Math.max(max, (prefix - start + m) % m); 40 | } 41 | 42 | // Update prefix tree. 43 | treeSet.add(prefix); 44 | } 45 | 46 | if (scanner.hasNextLine()) { 47 | scanner.nextLine(); 48 | } 49 | 50 | System.out.println(max); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/search/missing-numbers/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/search/missing-numbers/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/missing-numbers] (https://www.hackerrank.com/challenges/missing-numbers) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/search/missing-numbers/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define RANGE 101 5 | 6 | typedef std::vector list; 7 | 8 | template 9 | struct inc { 10 | inline T operator()(const T& value) { 11 | return value + 1; 12 | } 13 | }; 14 | 15 | template 16 | struct dec { 17 | inline T operator()(const T& value) { 18 | return value - 1; 19 | } 20 | }; 21 | 22 | template 23 | int calculate(list& frequencies, list& numbers, int begin) { // NOLINT 24 | Operator op; 25 | int size; 26 | std::cin >> size; 27 | while (size-- > 0) { 28 | int n; 29 | std::cin >> n; 30 | int index = n % RANGE; // Index where we want to place this number 31 | frequencies[index] = op(frequencies[index]); 32 | numbers[index] = n; 33 | if (begin == -1 || n < numbers[begin]) { 34 | begin = index; 35 | } 36 | } 37 | return begin; 38 | } 39 | 40 | int main() { 41 | std::vector frequencies(RANGE, 0); 42 | std::vector numbers(RANGE, 0); 43 | 44 | int begin = -1; 45 | begin = calculate>(frequencies, numbers, begin); 46 | begin = calculate>(frequencies, numbers, begin); 47 | 48 | for (size_t i = 0; i < frequencies.size(); ++i) { 49 | size_t index = (i + begin) % (RANGE - 1); 50 | if (frequencies[index] != 0) { 51 | std::cout << numbers[index] << " "; 52 | } 53 | } 54 | std::cout << std::endl; 55 | } 56 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/search/pairs/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/search/pairs/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/pairs](https://www.hackerrank.com/challenges/pairs) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/search/pairs/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | std::priority_queue buildqueue(std::istream& in, int N) { // NOLINT 6 | std::priority_queue queue; 7 | int i; 8 | while (N-- > 0) { 9 | in >> i; 10 | queue.push(i); 11 | } 12 | return queue; 13 | } 14 | 15 | int pairs(std::istream& in, int N, int K) { // NOLINT 16 | std::priority_queue queue = buildqueue(in, N); 17 | 18 | int index = 0, high = 0, count = 0; 19 | std::vector numbers(N); 20 | while (!queue.empty()) { 21 | numbers[index] = queue.top(); 22 | queue.pop(); 23 | while (high < index && numbers[high] > numbers[index] + K) { 24 | ++high; 25 | } 26 | if (numbers[high] == numbers[index] + K) { 27 | ++count; 28 | } 29 | ++index; 30 | } 31 | 32 | return count; 33 | } 34 | 35 | int main() { 36 | int N, K; 37 | std::cin >> N >> K; 38 | std::cout << pairs(std::cin, N, K) << std::endl; 39 | } 40 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/search/playing-with-numbers/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/search/playing-with-numbers/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/playing-with-numbers](https://www.hackerrank.com/challenges/playing-with-numbers) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/search/sherlock-and-array/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -stdlib=libc++ -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | run: 10 | ./out 11 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/search/sherlock-and-array/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/sherlock-and-array](https://www.hackerrank.com/challenges/sherlock-and-array) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/search/sherlock-and-array/SherlockAndArray.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | 3 | public class SherlockAndArray { 4 | public static void main(String[] args) { 5 | Scanner scanner = new Scanner(System.in); 6 | int t = Integer.parseInt(scanner.nextLine()); 7 | while (t > 0) { 8 | testCase(scanner); 9 | t--; 10 | } 11 | } 12 | 13 | public static void testCase(Scanner scanner) { 14 | int n = Integer.parseInt(scanner.nextLine()); 15 | int[] arr = new int[n]; 16 | for (int i = 0; i < n; i++) { 17 | arr[i] = scanner.nextInt(); 18 | } 19 | 20 | if (scanner.hasNextLine()) { 21 | scanner.nextLine(); 22 | } 23 | 24 | if (isSherlockArray(arr)) { 25 | System.out.println("YES"); 26 | } else { 27 | System.out.println("NO"); 28 | } 29 | } 30 | 31 | public static boolean isSherlockArray(int[] arr) { 32 | int left = 0; 33 | int right = arr.length - 1; 34 | int leftSum = 0; 35 | int rightSum = 0; 36 | while (left < right) { 37 | if (leftSum >= rightSum) { 38 | rightSum += arr[right]; 39 | right--; 40 | } else { 41 | leftSum += arr[left]; 42 | left++; 43 | } 44 | } 45 | return leftSum == rightSum; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/search/short-palindrome/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/search/short-palindrome/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/short-palindrome](https://www.hackerrank.com/challenges/short-palindrome) 4 | 5 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/sorting/quicksort-in-place/Makefile: -------------------------------------------------------------------------------- 1 | default: build run 2 | 3 | build: 4 | javac Solution.java 5 | 6 | run: 7 | java Solution 8 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/sorting/quicksort-in-place/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/quicksort3](https://www.hackerrank.com/challenges/quicksort3) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/sorting/quicksort-in-place/Solution.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | 3 | public class Solution { 4 | public static void main(String[] args) { 5 | Scanner scanner = new Scanner(System.in); 6 | 7 | int n = Integer.parseInt(scanner.nextLine()); 8 | int[] array = new int[n]; 9 | for (int i = 0; i < n; ++i) { 10 | array[i] = scanner.nextInt(); 11 | } 12 | 13 | quicksort(array, 0, array.length - 1); 14 | } 15 | 16 | public static void quicksort(int[] array, int lo, int hi) { 17 | if (lo >= hi) { 18 | return; 19 | } 20 | 21 | int partition = partition(array, lo, hi, hi); 22 | quicksort(array, lo, partition - 1); 23 | quicksort(array, partition + 1, hi); 24 | } 25 | 26 | public static int partition(int[] array, int lo, int hi, int pivot) { 27 | int store = lo; 28 | for (int i = lo; i < hi; ++i) { 29 | if (array[i] < array[pivot]) { 30 | swap(array, i, store); 31 | ++store; 32 | } 33 | } 34 | swap(array, pivot, store); 35 | printArray(array); 36 | 37 | return store; 38 | } 39 | 40 | public static void swap(int[] array, int a, int b) { 41 | int tmp = array[a]; 42 | array[a] = array[b]; 43 | array[b] = tmp; 44 | } 45 | 46 | public static void printArray(int[] array) { 47 | for (int i = 0; i < array.length; ++i) { 48 | if (i > 0) { 49 | System.out.print(" "); 50 | } 51 | System.out.print(array[i]); 52 | } 53 | System.out.println(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/strings/bigger-is-greater/Makefile: -------------------------------------------------------------------------------- 1 | default: build run 2 | 3 | build: 4 | javac Solution.java 5 | 6 | run: 7 | java Solution 8 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/strings/bigger-is-greater/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/bigger-is-greater](https://www.hackerrank.com/challenges/bigger-is-greater) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/strings/bigger-is-greater/Solution.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | 3 | /** 4 | * Algorithm explanation: http://www.nayuki.io/page/next-lexicographical-permutation-algorithm 5 | */ 6 | public class Solution { 7 | public static final String NO_ANSWER = "no answer"; 8 | 9 | public static void main(String[] args) { 10 | Scanner scanner = new Scanner(System.in); 11 | 12 | int n = scanner.nextInt(); 13 | scanner.nextLine(); 14 | 15 | while (n > 0) { 16 | String permutation = nextPermutation(scanner.nextLine()); 17 | System.out.println(permutation); 18 | n--; 19 | } 20 | } 21 | 22 | public static String nextPermutation(String str) { 23 | char[] c = str.toCharArray(); 24 | 25 | // Find pivot 26 | int i = c.length - 2; 27 | while (i >= 0 && c[i] >= c[i + 1]) { 28 | i--; 29 | } 30 | 31 | if (i < 0) { 32 | return NO_ANSWER; 33 | } 34 | 35 | // Find smallest element in suffix that is >= pivot 36 | int swap = i + 1; 37 | for (int n = swap; n < c.length; n++) { 38 | if (c[n] <= c[swap] && c[n] > c[i]) { 39 | swap = n; 40 | } 41 | } 42 | 43 | // Swap pivot and minimal element in suffix. 44 | c[i] ^= c[swap]; 45 | c[swap] ^= c[i]; 46 | c[i] ^= c[swap]; 47 | 48 | // Reverse (sort) suffix. 49 | int left = i + 1; 50 | int right = c.length - 1; 51 | while (left < right) { 52 | c[left] ^= c[right]; 53 | c[right] ^= c[left]; 54 | c[left] ^= c[right]; 55 | left++; 56 | right--; 57 | } 58 | 59 | return new String(c); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/strings/common-child/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/strings/common-child/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/common-child](https://www.hackerrank.com/challenges/common-child) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/strings/common-child/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | uint32_t lcs(const std::string& a, const std::string& b) { 6 | size_t m = a.length() + 1; 7 | size_t n = b.length() + 1; 8 | std::vector> cache(m, std::vector(n)); 9 | for (size_t i = 0; i < m; ++i) { 10 | for (size_t j = 0; j < n; ++j) { 11 | if (i == 0 || j == 0) { 12 | cache[i][j] = 0; 13 | } else if (a[i - 1] == b[j - 1]) { 14 | cache[i][j] = cache[i - 1][j - 1] + 1; 15 | } else { 16 | cache[i][j] = std::max(cache[i][j - 1], cache[i - 1][j]); 17 | } 18 | } 19 | } 20 | return cache[a.length()][b.length()]; 21 | } 22 | 23 | int main() { 24 | std::string a, b; 25 | std::cin >> a; 26 | std::cin >> b; 27 | std::cout << lcs(a, b) << std::endl; 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/strings/pangrams/Makefile: -------------------------------------------------------------------------------- 1 | default: build run 2 | 3 | build: 4 | javac Solution.java 5 | 6 | run: 7 | java Solution 8 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/strings/pangrams/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/pangrams](https://www.hackerrank.com/challenges/pangrams) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/strings/pangrams/Solution.java: -------------------------------------------------------------------------------- 1 | import java.io.IOException; 2 | 3 | public class Solution { 4 | public static void main(String[] args) throws IOException { 5 | // Tracks xor between alphabet and string characters 6 | int xor = 0; 7 | 8 | // Each "on" bit represents an occurence of a character 9 | int alphas = 0; 10 | 11 | // xor the alphabet characters together 12 | for (int i = 0; i < 26; i++) { 13 | xor ^= i; 14 | } 15 | 16 | int c; 17 | while ((c = System.in.read()) != -1) { 18 | c = Character.toLowerCase(c); 19 | if (c < 'a' || c > 'z') continue; 20 | c -= 'a'; 21 | if (((alphas >> c) & 1) == 1) continue; 22 | xor ^= c; 23 | alphas |= 1 << c; 24 | } 25 | 26 | if (xor == 0) { 27 | System.out.println("pangram"); 28 | } else { 29 | System.out.println("not pangram"); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/strings/sherlock-and-anagrams/Makefile: -------------------------------------------------------------------------------- 1 | default: build run 2 | 3 | build: 4 | javac Solution.java 5 | 6 | run: 7 | java Solution 8 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/strings/sherlock-and-anagrams/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/sherlock-and-anagrams](https://www.hackerrank.com/challenges/sherlock-and-anagrams) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/strings/sherlock-and-anagrams/Solution.java: -------------------------------------------------------------------------------- 1 | import java.util.Arrays; 2 | import java.util.HashMap; 3 | import java.util.Scanner; 4 | 5 | public class Solution { 6 | public static void main(String[] args) { 7 | Scanner in = new Scanner(System.in); 8 | 9 | int T = in.nextInt(); 10 | in.nextLine(); 11 | 12 | while (T > 0) { 13 | testCase(in); 14 | T--; 15 | } 16 | } 17 | 18 | public static void testCase(Scanner in) { 19 | String str = in.nextLine(); 20 | 21 | HashMap map = new HashMap(); 22 | 23 | // Count the number of substrings that form each anagram. 24 | for (int i = 0; i < str.length(); i++) { 25 | for (int n = i; n < str.length(); n++) { 26 | char[] substr = str.substring(i, n + 1).toCharArray(); 27 | Arrays.sort(substr); 28 | String key = new String(substr); 29 | if (!map.containsKey(key)) { 30 | map.put(key, 1); 31 | } else { 32 | map.put(key, map.get(key) + 1); 33 | } 34 | } 35 | } 36 | 37 | // Count the number of substring pairs that form each anagram. 38 | int count = 0; 39 | for (int subs : map.values()) { 40 | count += subs * (subs - 1) * 0.5; 41 | } 42 | 43 | System.out.println(count); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/strings/two-strings/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/two-strings](https://www.hackerrank.com/challenges/two-strings) 4 | -------------------------------------------------------------------------------- /hacker-rank/algorithms/strings/two-strings/two-strings.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | 5 | 6 | def char_set(string): 7 | chars = {} 8 | for c in string: 9 | chars[c] = True 10 | return chars 11 | 12 | 13 | def test_case(): 14 | A = sys.stdin.readline().strip() 15 | B = sys.stdin.readline().strip() 16 | bCharSet = char_set(B) 17 | for c in A: 18 | if (c in bCharSet): 19 | print("YES") 20 | return 21 | print("NO") 22 | 23 | 24 | def main(): 25 | T = int(sys.stdin.readline()) 26 | while (T > 0): 27 | test_case() 28 | T -= 1 29 | 30 | if __name__ == '__main__': 31 | main() 32 | -------------------------------------------------------------------------------- /hacker-rank/artificial-intelligence/alpha-beta-pruning/tic-tac-toe/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/tic-tac-toe](https://www.hackerrank.com/challenges/tic-tac-toe) 4 | 5 | -------------------------------------------------------------------------------- /hacker-rank/data-structures/disjoint-set/merging-communities/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /hacker-rank/data-structures/disjoint-set/merging-communities/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/merging-communities](https://www.hackerrank.com/challenges/merging-communities) 4 | -------------------------------------------------------------------------------- /hacker-rank/data-structures/disjoint-set/merging-communities/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | // 7 | // DisjointSets class is an efficient implementation of a union-find data 8 | // structure that tracks a collection of elements partitioned into disjoint 9 | // sets. 10 | // 11 | // Path compression is used to improve merge and find performance. 12 | // 13 | class DisjointSets { 14 | private: 15 | struct Set { 16 | int parent = -1; 17 | 18 | size_t size = 1; 19 | }; 20 | 21 | std::vector objects; 22 | 23 | public: 24 | explicit DisjointSets(size_t n) : objects(n) { 25 | } 26 | 27 | // 28 | // Merges the two sets l and r belong to. This is a no-op if l and r are 29 | // already part of the same set. Otherwise, the set with elements becomes a 30 | // child of the larger set. 31 | // 32 | // Returns the root set of the merge operation. 33 | // 34 | size_t merge(size_t l, size_t r) { 35 | l = find(l); 36 | r = find(r); 37 | if (l == r) { 38 | return l; 39 | } else if (objects[l].size < objects[r].size) { 40 | return merge(r, l); 41 | } 42 | objects[r].parent = l; 43 | objects[l].size += objects[r].size; 44 | return l; 45 | } 46 | 47 | // 48 | // Finds the root of the set i is in while performing path compression. 49 | // 50 | size_t find(size_t i) { 51 | if (objects[i].parent == -1) { 52 | return i; 53 | } 54 | objects[i].parent = find(objects[i].parent); 55 | return objects[i].parent; 56 | } 57 | 58 | // 59 | // Returns the size of the set i belongs to. 60 | // 61 | size_t size(size_t i) { 62 | return objects[find(i)].size; 63 | } 64 | }; 65 | 66 | int main() { 67 | size_t N, Q; 68 | std::cin >> N >> Q; 69 | 70 | // Ignore until EOL 71 | std::string line; 72 | std::getline(std::cin, line); 73 | 74 | DisjointSets ds(N); 75 | 76 | // Process each query... 77 | while (std::getline(std::cin, line)) { 78 | std::stringstream ss(line); 79 | char type; 80 | ss >> type; 81 | size_t I, J; 82 | ss >> I >> J; 83 | I--; J--; 84 | switch (type) { 85 | case 'M': 86 | ds.merge(I, J); 87 | break; 88 | case 'Q': 89 | std::cout << ds.size(I) << std::endl; 90 | break; 91 | default: 92 | std::cerr << "Invalid query " << type << "!" << std::endl; 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /hacker-rank/data-structures/heap/find-median/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/find-median-1](https://www.hackerrank.com/challenges/find-median-1) 4 | -------------------------------------------------------------------------------- /hacker-rank/data-structures/heap/find-median/find-median.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | import heapq 5 | 6 | 7 | class Median(object): 8 | def __init__(self): 9 | self.min = [] 10 | self.max = [] 11 | 12 | def add(self, num): 13 | if (len(self.max) > len(self.min)): 14 | if (num >= -self.max[0]): 15 | heapq.heappush(self.min, num) 16 | else: 17 | heapq.heappush(self.min, -heapq.heappop(self.max)) 18 | heapq.heappush(self.max, -num) 19 | else: 20 | if (len(self.min) > 0 and num >= self.min[0]): 21 | heapq.heappush(self.max, -heapq.heappop(self.min)) 22 | heapq.heappush(self.min, num) 23 | else: 24 | heapq.heappush(self.max, -num) 25 | 26 | def median(self): 27 | if (len(self.max) == len(self.min)): 28 | return (-self.max[0] + self.min[0]) / 2 29 | else: 30 | return -self.max[0] 31 | 32 | 33 | def main(): 34 | N = int(sys.stdin.readline()) 35 | m = Median() 36 | while (N > 0): 37 | i = int(sys.stdin.readline()) 38 | m.add(i) 39 | print(m.median()) 40 | N = N - 1 41 | 42 | if __name__ == "__main__": 43 | main() 44 | -------------------------------------------------------------------------------- /hacker-rank/data-structures/tree/bst-lowest-common-ancestor/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /hacker-rank/data-structures/tree/bst-lowest-common-ancestor/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/binary-search-tree-lowest-common-ancestor](https://www.hackerrank.com/challenges/binary-search-tree-lowest-common-ancestor) 4 | -------------------------------------------------------------------------------- /hacker-rank/data-structures/tree/bst-lowest-common-ancestor/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define DEV 1 4 | 5 | #if DEV 6 | struct node { 7 | int data; 8 | node* left; 9 | node* right; 10 | }; 11 | #endif 12 | 13 | bool contains(node* root, int value) { 14 | if (root == nullptr) { 15 | return false; 16 | } else if (root->data == value) { 17 | return true; 18 | } else if (root->data < value) { 19 | return contains(root->right, value); 20 | } else { 21 | return contains(root->left, value); 22 | } 23 | } 24 | 25 | node* lca_helper(node* root, int a, int b) { 26 | if (root == nullptr) { 27 | return nullptr; 28 | } 29 | 30 | if (root->data == a || root->data == b) { 31 | return root; 32 | } 33 | 34 | bool left = contains(root->left, a); 35 | 36 | if (left != contains(root->left, b)) { 37 | return root; 38 | } 39 | 40 | root = left == true ? root->left : root->right; 41 | return lca_helper(root, a, b); 42 | } 43 | 44 | node* lca(node* root, int a, int b) { 45 | if (!contains(root, a) || !contains(root, b)) { 46 | return nullptr; 47 | } 48 | return lca_helper(root, a, b); 49 | } 50 | 51 | #if DEV 52 | int main() { 53 | node left {1}; 54 | node right {3}; 55 | node root {2, &left, &right}; 56 | 57 | node* ancestor = lca(&root, 1, 3); 58 | if (ancestor == &root) { 59 | std::cout << "LCA of 1 and 3 is " << ancestor->data << std::endl; 60 | } else { 61 | std::cerr << "Error!" << std::endl; 62 | } 63 | 64 | return 0; 65 | } 66 | #endif 67 | -------------------------------------------------------------------------------- /hacker-rank/data-structures/tree/median-updates/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/median](https://www.hackerrank.com/challenges/median) 4 | -------------------------------------------------------------------------------- /hacker-rank/data-structures/tree/self-balancing-tree/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /hacker-rank/data-structures/tree/self-balancing-tree/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/self-balancing-tree](https://www.hackerrank.com/challenges/self-balancing-tree) 4 | -------------------------------------------------------------------------------- /hacker-rank/data-structures/trie/no-prefix-set/Makefile: -------------------------------------------------------------------------------- 1 | default: build run 2 | 3 | build: 4 | javac Solution.java 5 | 6 | run: 7 | java Solution 8 | -------------------------------------------------------------------------------- /hacker-rank/data-structures/trie/no-prefix-set/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/no-prefix-set](https://www.hackerrank.com/challenges/no-prefix-set) 4 | -------------------------------------------------------------------------------- /hacker-rank/data-structures/trie/no-prefix-set/Solution.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | 3 | class TrieNode { 4 | public boolean eos; 5 | 6 | public TrieNode[] children; 7 | 8 | public static int RANGE = 'j' - 'a' + 1; 9 | 10 | public TrieNode() { 11 | this.eos = true; 12 | this.children = new TrieNode[RANGE]; 13 | } 14 | } 15 | 16 | class Trie { 17 | private TrieNode root; 18 | 19 | public Trie() { 20 | this.root = new TrieNode(); 21 | } 22 | 23 | public boolean add(String word) { 24 | TrieNode node = root; 25 | int index = 0; 26 | while (index < word.length()) { 27 | node.eos = false; 28 | char c = word.charAt(index); 29 | int i = c - 'a'; 30 | if (node.children[i] == null) { 31 | node.children[i] = new TrieNode(); 32 | } else if (node.children[i].eos || index == word.length() - 1) { 33 | return false; 34 | } 35 | node = node.children[i]; 36 | index++; 37 | } 38 | return true; 39 | } 40 | } 41 | 42 | public class Solution { 43 | public static void main(String[] args) { 44 | Scanner scanner = new Scanner(System.in); 45 | 46 | int N = scanner.nextInt(); 47 | scanner.nextLine(); 48 | 49 | Trie trie = new Trie(); 50 | 51 | for (int i = 0; i < N; i++) { 52 | String word = scanner.nextLine(); 53 | if (!trie.add(word)) { 54 | System.out.println("BAD SET"); 55 | System.out.println(word); 56 | return; 57 | } 58 | } 59 | 60 | System.out.println("GOOD SET"); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /hacker-rank/mathematics/combinatorics/choose-and-calculate/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /hacker-rank/mathematics/combinatorics/choose-and-calculate/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/choose-and-calculate](https://www.hackerrank.com/challenges/choose-and-calculate) 4 | -------------------------------------------------------------------------------- /hacker-rank/mathematics/combinatorics/journey-to-mars/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /hacker-rank/mathematics/combinatorics/journey-to-mars/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/ajourney](https://www.hackerrank.com/challenges/ajourney) 4 | -------------------------------------------------------------------------------- /hacker-rank/mathematics/combinatorics/journey-to-mars/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /** 5 | * Returns an integer equal to the first K digits of 2^N. 6 | */ 7 | uint64_t first_k(int N, int K) { 8 | long double f = N * std::log10(2.0L); 9 | f -= static_cast(f); 10 | f = std::pow(10.0, f); 11 | f *= std::pow(10, K - 1); 12 | return f; 13 | } 14 | 15 | /** 16 | * Returns an integer equal to the last K digits of 2^log10(mod) 17 | */ 18 | uint64_t last_k(const int& N, const int& mod) { 19 | if (N == 0) { 20 | return 1; 21 | } else if (N % 2 == 0) { 22 | uint64_t mod_root = last_k(N / 2, mod) % mod; 23 | return (mod_root * mod_root) % mod; 24 | } else { 25 | return (2 * last_k(N - 1, mod)) % mod; 26 | } 27 | } 28 | 29 | int main() { 30 | int T, N, K; 31 | std::cin >> T; 32 | while (T-- > 0) { 33 | std::cin >> N >> K; 34 | uint64_t first = first_k(N - 1, K); 35 | uint64_t last = last_k(N - 1, static_cast(std::pow(10, K))); 36 | std::cout << first + last << std::endl; 37 | } 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /hacker-rank/mathematics/combinatorics/ncr-table/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /hacker-rank/mathematics/combinatorics/ncr-table/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/challenges/ncr-table](https://www.hackerrank.com/challenges/ncr-table) 4 | -------------------------------------------------------------------------------- /hacker-rank/mathematics/combinatorics/ncr-table/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | const uint64_t MOD = 1000000000; 5 | 6 | class nCr { 7 | private: 8 | std::vector> cache; 9 | 10 | uint64_t mod; 11 | 12 | public: 13 | nCr(uint64_t n, uint64_t mod) : 14 | cache(n, std::vector(n, 0)), 15 | mod(mod) { 16 | } 17 | 18 | uint64_t calculate(uint64_t n, uint64_t r) { 19 | if (n == 0 || r == 0 || r == n) { 20 | return 1; 21 | } else if (this->cache[n - 1][r - 1] != 0) { 22 | return this->cache[n - 1][r - 1]; 23 | } 24 | uint64_t a = this->calculate(n - 1, r - 1); 25 | uint64_t b = this->calculate(n - 1, r); 26 | this->cache[n - 1][r - 1] = (a % this->mod + b % this->mod) % this->mod; 27 | return this->cache[n - 1][r - 1]; 28 | } 29 | }; 30 | 31 | void run(uint16_t n, std::ostream &out) { // NOLINT 32 | nCr ncr(n, MOD); 33 | for (uint16_t r = 0; r <= n; r++) { 34 | out << ncr.calculate(n, r) << " "; 35 | } 36 | out << std::endl; 37 | } 38 | 39 | int main() { 40 | uint16_t T; 41 | std::cin >> T; 42 | while (T--) { 43 | uint16_t n; 44 | std::cin >> n; 45 | run(n, std::cout); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /hacker-rank/mathematics/combinatorics/rank-of-a-word/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://www.hackerrank.com/contests/rtc-v32/challenges/rank-of-a-word](https://www.hackerrank.com/contests/rtc-v32/challenges/rank-of-a-word) 4 | 5 | -------------------------------------------------------------------------------- /hacker-rank/mathematics/combinatorics/rank-of-a-word/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | 5 | 6 | def factorial(n): 7 | """ 8 | Naively calculates n! 9 | """ 10 | f = 1 11 | while n > 0: 12 | f *= n 13 | n -= 1 14 | return f 15 | 16 | 17 | def count(values): 18 | """ 19 | Returns a dict of counts for each value in the iterable. 20 | """ 21 | counts = dict() 22 | for v in values: 23 | if v not in counts: 24 | counts[v] = 0 25 | counts[v] += 1 26 | return counts 27 | 28 | 29 | def rank(word, i, chars): 30 | """ 31 | Finds the rank of word[i:] amongs permutations of characters in words[i:]. 32 | 33 | :type word: str 34 | :type i: int 35 | :type chars: Dict[chr, int] The count of each character in word[i:] 36 | """ 37 | n = len(word) 38 | assert i >= 0 39 | assert i < n 40 | if i == n - 1: 41 | return 0 42 | 43 | # The first character of the word[i:]. 44 | c = word[i] 45 | 46 | # The number of characters less than word[i] in word[i:]. Helps count the 47 | # number of words starting with a character less than word[i]. 48 | lt = 0 49 | for j in range(i, n): 50 | k = word[j] 51 | if k < c: 52 | lt += 1 53 | 54 | # Count the number of words starting with a character less than word[i]. 55 | r = lt * factorial(n - i - 1) 56 | 57 | # Remove identical permutations from duplicate characters. 58 | for k in chars: 59 | r /= factorial(chars[k]) 60 | 61 | # Recurse for word[i + 1:]. 62 | chars[c] -= 1 63 | r = int(r) + rank(word, i + 1, chars) 64 | chars[c] += 1 65 | return r 66 | 67 | 68 | def main(): 69 | T = int(sys.stdin.readline()) 70 | for _ in range(0, T): 71 | word = sys.stdin.readline().strip() 72 | chars = count(word) 73 | print(rank(word, 0, chars) + 1) 74 | 75 | if __name__ == '__main__': 76 | main() 77 | -------------------------------------------------------------------------------- /leetcode/algorithms/4sum/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/4sum/](https://leetcode.com/problems/4sum/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/basic-calculator/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/basic-calculator/](https://leetcode.com/problems/basic-calculator/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/binary-tree-inorder-postorder/Makefile: -------------------------------------------------------------------------------- 1 | LIBS := ../libs 2 | JAVA := java 3 | JAVAC := javac 4 | JAVACFLAGS := -Xlint:all 5 | 6 | default: clean build run 7 | 8 | build: 9 | make -C $(LIBS) 10 | mv $(LIBS)/*.class . 11 | $(JAVAC) $(JAVACFLAGS) *.java 12 | 13 | clean: 14 | make -C $(LIBS) clean 15 | $(RM) *.class 16 | 17 | run: 18 | $(JAVA) -ea Solution 19 | -------------------------------------------------------------------------------- /leetcode/algorithms/binary-tree-inorder-postorder/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/](https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/binary-tree-inorder-postorder/Solution.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | 4 | public class Solution { 5 | public TreeNode buildTree(int[] inorder, int[] postorder) { 6 | if (inorder == null || postorder == null 7 | || inorder.length != postorder.length) { 8 | throw new IllegalArgumentException( 9 | "inorder and postorder must be non-null and same length."); 10 | } 11 | return buildTree(inorder, 0, inorder.length - 1, 12 | postorder, 0, postorder.length - 1); 13 | } 14 | 15 | // 16 | // Builds a tree using inorder[iStart:iEnd + 1] and 17 | // postorder[pStart:pEnd + 1]. 18 | // 19 | private TreeNode buildTree(int[] inorder, int iStart, int iEnd, 20 | int[] postorder, int pStart, int pEnd) { 21 | // Check if inorder and postorder sub-lists are empty. 22 | if (pStart > pEnd) { 23 | return null; 24 | } 25 | 26 | // The last element in postorder is a root. 27 | TreeNode root = new TreeNode(postorder[pEnd]); 28 | 29 | // Check if there are any nodes left. 30 | if (pStart == pEnd) { 31 | return root; 32 | } 33 | 34 | // Find where the root value occurs in the inorder traversal. 35 | int i = find(inorder, iStart, iEnd, root.val); 36 | assert i != -1; 37 | 38 | // Split left and right side to solve recursively. 39 | int leftSize = i - iStart; 40 | root.left = buildTree(inorder, iStart, i - 1, 41 | postorder, pStart, pStart + leftSize - 1); 42 | root.right = buildTree(inorder, i + 1, iEnd, 43 | postorder, pStart + leftSize, pEnd - 1); 44 | return root; 45 | } 46 | 47 | // 48 | // Returns the index i where value occurs in order[start:end + 1] or 49 | // -1 if the value does not exist. 50 | // 51 | private int find(int[] order, int start, int end, int value) { 52 | for (int i = start; i <= end; i++) { 53 | if (order[i] == value) { 54 | return i; 55 | } 56 | } 57 | return -1; 58 | } 59 | 60 | public static void main(String[] args) { 61 | System.out.println("Please run this solution on LeetCode."); 62 | System.out.println("https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/"); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /leetcode/algorithms/binary-tree-inorder-preorder/Makefile: -------------------------------------------------------------------------------- 1 | LIBS := ../libs 2 | JAVA := java 3 | JAVAC := javac 4 | JAVACFLAGS := -Xlint:all 5 | 6 | default: clean build run 7 | 8 | build: 9 | make -C $(LIBS) 10 | mv $(LIBS)/*.class . 11 | $(JAVAC) $(JAVACFLAGS) *.java 12 | 13 | clean: 14 | make -C $(LIBS) clean 15 | $(RM) *.class 16 | 17 | run: 18 | $(JAVA) -ea Solution 19 | -------------------------------------------------------------------------------- /leetcode/algorithms/binary-tree-inorder-preorder/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/binary-tree-inorder-preorder/Solution.java: -------------------------------------------------------------------------------- 1 | import java.util.HashMap; 2 | import java.util.ArrayList; 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | public class Solution { 7 | public TreeNode buildTree(int[] preorder, int[] inorder) { 8 | if (preorder == null || inorder == null || preorder.length != inorder.length) { 9 | throw new IllegalArgumentException( 10 | "preorder and inorder must be non-null and same length."); 11 | } 12 | return buildTree(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1); 13 | } 14 | 15 | // 16 | // Builds a tree using preorder[pStart:pEnd + 1] and inorder[iStart:iEnd + 1]. 17 | // 18 | private TreeNode buildTree(int[] preorder, int pStart, int pEnd, 19 | int[] inorder, int iStart, int iEnd) { 20 | // Check if preorded and inorder sub-lists are empty. 21 | if (pStart > pEnd) { 22 | return null; 23 | } 24 | 25 | // The first element in preorder is a root. 26 | TreeNode root = new TreeNode(preorder[pStart]); 27 | 28 | // Check if there are any nodes left. 29 | if (pStart == pEnd) { 30 | return root; 31 | } 32 | 33 | // Find where the root value occurs in the inorder traversal. 34 | int i = find(inorder, iStart, iEnd, root.val); 35 | assert i != -1; 36 | 37 | // Split left and right side to solve recursively. 38 | int leftSize = i - iStart; 39 | root.left = buildTree(preorder, pStart + 1, pStart + leftSize, 40 | inorder, iStart, i - 1); 41 | root.right = buildTree(preorder, pStart + 1 + leftSize, pEnd, 42 | inorder, i + 1, iEnd); 43 | return root; 44 | } 45 | 46 | // 47 | // Returns the index i where value occurs in order[start:end + 1] or -1 if 48 | // the value does not exist. 49 | // 50 | private int find(int[] order, int start, int end, int value) { 51 | for (int i = start; i <= end; i++) { 52 | if (order[i] == value) { 53 | return i; 54 | } 55 | } 56 | return -1; 57 | } 58 | 59 | public static void main(String[] args) { 60 | System.out.println("Please run this solution on LeetCode."); 61 | System.out.println("https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/"); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /leetcode/algorithms/binary-tree-max-path-sum/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/binary-tree-maximum-path-sum/](https://leetcode.com/problems/binary-tree-maximum-path-sum/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/binary-tree-max-path-sum/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 4 | class Solution(object): 5 | def _maxPathSum(self, root): 6 | """ 7 | Returns a tuple representing the maximum length of several path types 8 | within root. 9 | 10 | Type I - Paths starting at root. Can be extended by parents of root. 11 | Type II - Paths NOT starting at root. These paths might be in the left 12 | or right children and not contain root, or in both the left 13 | and right children joined by and containing root. These paths 14 | cannot be extended by parents of root. 15 | """ 16 | if root is None: 17 | return (float('-inf'), float('-inf')) 18 | 19 | left = self._maxPathSum(root.left) 20 | right = self._maxPathSum(root.right) 21 | 22 | # Calculate max length of Type I path. 23 | startWithChild = max(left[0], right[0]) 24 | startWithRoot = root.val + max(0, startWithChild) 25 | 26 | # Calculate max length of Type II path. Begin by finding largest path 27 | # within the child sub-trees. 28 | withinChildren = max(max(left), max(right)) 29 | 30 | # Now try creating a path by joining the two top level paths from the 31 | # left and right sub-tree with the current node. 32 | joinWithRoot = root.val + left[0] + right[0] 33 | 34 | # Select the max length Type II path. 35 | typeTwo = max(withinChildren, joinWithRoot) 36 | 37 | return (startWithRoot, typeTwo) 38 | 39 | def maxPathSum(self, root): 40 | assert root is not None 41 | return max(self._maxPathSum(root)) 42 | 43 | 44 | def main(): 45 | print('Please run this solution on LeetCode.') 46 | print('https://leetcode.com/problems/binary-tree-maximum-path-sum/') 47 | 48 | if __name__ == '__main__': 49 | main() 50 | -------------------------------------------------------------------------------- /leetcode/algorithms/binary-tree-zigzag-level-order/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/](https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/burst-balloons/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/burst-balloons/](https://leetcode.com/problems/burst-balloons/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/burst-balloons/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 4 | class Solution(object): 5 | def maxCoins(self, balloons): 6 | """Returns the max coins with an optimal popping strategy. 7 | 8 | Args: 9 | balloons (List[int]): Balloon coin values. 10 | 11 | Returns: 12 | The max coins as an int. 13 | """ 14 | n = len(balloons) 15 | if n == 0: 16 | return 0 17 | elif n == 1: 18 | return balloons[0] 19 | 20 | # Each dp[i][j] stores the max coins one can get by popping 21 | # balloons[i...j] BEFORE balloon i and j. 22 | dp = [[-1 for _ in xrange(n)] for _ in xrange(n)] 23 | 24 | return self.maxCoinsHelper(balloons, 0, n - 1, dp, 1, 1) 25 | 26 | def maxCoinsHelper(self, balloons, lo, hi, dp, left, right): 27 | """Returns the max coins popping balloons[lo...hi] optimally. 28 | 29 | The overall strategy is that each time we consider each balloon x as 30 | the LAST balloon we will pop in balloons[lo...hi]. This way we can 31 | be sure that the left/right adjacent balloon for the sub-problems will 32 | be x. 33 | """ 34 | if hi < 0 or lo >= len(dp): 35 | return 0 36 | elif dp[lo][hi] != -1: 37 | return dp[lo][hi] 38 | elif lo == hi: 39 | # This works because left = balloons[lo - 1] and right = 40 | # balloons[hi + 1] each time dp[i][i] is reused. See definition of 41 | # dp array in maxCoins(...) function. 42 | dp[lo][hi] = left * balloons[lo] * right 43 | return dp[lo][hi] 44 | 45 | coins = 0 46 | 47 | for i in xrange(lo, hi + 1): 48 | x = balloons[i] # Last balloon we will pop in balloons[lo...hi]. 49 | leftCoins = self.maxCoinsHelper(balloons, lo, i - 1, dp, left, x) 50 | rightCoins = self.maxCoinsHelper(balloons, i + 1, hi, dp, x, right) 51 | coins = max(coins, leftCoins + left * x * right + rightCoins) 52 | 53 | dp[lo][hi] = coins 54 | return coins 55 | 56 | 57 | def main(): 58 | print('Please run this solution on LeetCode.') 59 | print('https://leetcode.com/problems/burst-balloons/') 60 | 61 | if __name__ == '__main__': 62 | main() 63 | -------------------------------------------------------------------------------- /leetcode/algorithms/closest-palindrome/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /leetcode/algorithms/closest-palindrome/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/contest/leetcode-weekly-contest-29/problems/find-the-closest-palindrome/](https://leetcode.com/contest/leetcode-weekly-contest-29/problems/find-the-closest-palindrome/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/container-with-most-water/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/container-with-most-water/](https://leetcode.com/problems/container-with-most-water/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/container-with-most-water/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 4 | class Solution(object): 5 | def maxArea(self, heights): 6 | """ 7 | Given a list of line heights, finds the largest container between two 8 | lines. Good explanation of the algorithm can be found at 9 | https://discuss.leetcode.com/topic/3462/yet-another-way-to-see-what-happens-in-the-o-n-algorith # nopep8 10 | """ 11 | n = len(heights) 12 | if n < 2: 13 | return 0 14 | 15 | maxArea = 0 16 | left = 0 17 | right = n - 1 18 | 19 | while (left < right): 20 | # Calculate the area for this pair of left/right lines and check if 21 | # this is a new maximum area. 22 | h = min(heights[left], heights[right]) 23 | area = h * (right - left) 24 | maxArea = max(maxArea, area) 25 | 26 | if heights[left] < heights[right]: 27 | # If right line is higher than left line, there is no right 28 | # line further from the left than the current one. 29 | left += 1 30 | elif heights[right] < heights[left]: 31 | # If left line is higher than right line, there is no left 32 | # line further from the right than the current one. 33 | right -= 1 34 | else: 35 | # If both the left and right lines are the same height, then 36 | # both of the above cases hold. 37 | left += 1 38 | right -= 1 39 | 40 | return maxArea 41 | 42 | 43 | def main(): 44 | print('Please run this solution on LeetCode.') 45 | print('https://leetcode.com/problems/container-with-most-water/') 46 | 47 | if __name__ == '__main__': 48 | main() 49 | -------------------------------------------------------------------------------- /leetcode/algorithms/contains-duplicate-iii/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /leetcode/algorithms/contains-duplicate-iii/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/contains-duplicate-iii/](https://leetcode.com/problems/contains-duplicate-iii/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/contains-duplicate-iii/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | class Solution { 6 | public: 7 | // 8 | // Checks if there are at least two indexes i and j such that abs(i - j) <= 9 | // abs(k) and abs(nums[i], [j]) <= t. 10 | // 11 | bool containsNearbyAlmostDuplicate(const std::vector nums, 12 | int k, int t) { 13 | // Absolute difference < 0 is not possible. Also, no way to have a pair of 14 | // (i, j) where i != j if i - j == 0. 15 | if (t < 0 || k == 0) { 16 | return false; 17 | } 18 | 19 | // For ease of index comparison. 20 | k = abs(k); 21 | 22 | // Track last k elements and number of occurences in sorted order. 23 | std::map history; 24 | 25 | int size = nums.size(); 26 | for (int i = 0; i < size; ++i) { 27 | int n = nums[i]; 28 | 29 | // Get smallest in range element while accounting for underflow. 30 | int lo = n - t; 31 | if (lo > n) { 32 | lo = std::numeric_limits::min(); 33 | } 34 | 35 | // Get largest in range element while accounting for overflow. 36 | int hi = n + t; 37 | if (hi < n) { 38 | hi = std::numeric_limits::max(); 39 | } 40 | 41 | // Find first element >= lo. 42 | auto firstGTElo = history.lower_bound(lo); 43 | 44 | // Check if it is in bounds. 45 | if (firstGTElo != history.end() && firstGTElo->first <= hi) { 46 | return true; 47 | } 48 | 49 | // Update count of this element. 50 | history[n]++; 51 | 52 | // Trim trailing elements. 53 | if (i >= k) { 54 | int toRemove = nums[i - k]; 55 | history[toRemove]--; 56 | if (history[toRemove] <= 0) { 57 | history.erase(toRemove); 58 | } 59 | } 60 | } 61 | 62 | return false; 63 | } 64 | }; 65 | 66 | 67 | // 68 | // Delete before submitting to LeetCode. 69 | // 70 | int main() { 71 | } 72 | -------------------------------------------------------------------------------- /leetcode/algorithms/data-stream-disjoint-intervals/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /leetcode/algorithms/data-stream-disjoint-intervals/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/data-stream-as-disjoint-intervals/](https://leetcode.com/problems/data-stream-as-disjoint-intervals/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/different-ways-to-add-parenthesis/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/different-ways-to-add-parentheses/](https://leetcode.com/problems/different-ways-to-add-parentheses/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/distinct-subsequences/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/distinct-subsequences/](https://leetcode.com/problems/distinct-subsequences/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/distinct-subsequences/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 4 | class Solution(object): 5 | def numDistinct(self, s, t): 6 | """ 7 | Counts the number of distinct subequences of t in s. 8 | """ 9 | n = len(s) 10 | m = len(t) 11 | if n == 0 or m == 0: 12 | return 0 13 | 14 | # 15 | # Setup the DP. Each entry dp[i][j] represents the number of distinct 16 | # subsequences of t[:i] in s[:j]. Each prefix of s has exactly one 17 | # distinct empty subsequence. 18 | # 19 | dp = [[0 for j in range(0, n + 1)] for i in range(0, m + 1)] 20 | for j in range(0, n + 1): 21 | dp[0][j] = 1 22 | 23 | for i in range(1, m + 1): 24 | for j in range(1, n + 1): 25 | # Include the number of distinct t[:i] in s[:j - 1] in the 26 | # number of distinct t[:i] in s[:j]. 27 | dp[i][j] = dp[i][j - 1] 28 | 29 | # If the last characters of each string match, also count the 30 | # number of distinct t[:i - 1] in s[:j - 1]. 31 | if t[i - 1] == s[j - 1]: 32 | dp[i][j] += dp[i - 1][j - 1] 33 | 34 | return dp[-1][-1] 35 | 36 | 37 | def main(): 38 | print('Please run this solution on LeetCode.') 39 | print('https://leetcode.com/problems/distinct-subsequences/') 40 | 41 | if __name__ == '__main__': 42 | main() 43 | -------------------------------------------------------------------------------- /leetcode/algorithms/dungeon-game/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/dungeon-game/](https://leetcode.com/problems/dungeon-game/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/edit-distance/Makefile: -------------------------------------------------------------------------------- 1 | JAVA := java 2 | JAVAC := javac 3 | JAVACFLAGS := -Xlint:all 4 | 5 | default: clean build run 6 | 7 | build: 8 | $(JAVAC) $(JAVACFLAGS) Solution.java 9 | 10 | clean: 11 | $(RM) Solution.class 12 | 13 | run: 14 | $(JAVA) Solution 15 | -------------------------------------------------------------------------------- /leetcode/algorithms/edit-distance/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/edit-distance/](https://leetcode.com/problems/edit-distance/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/edit-distance/Solution.java: -------------------------------------------------------------------------------- 1 | public class Solution { 2 | // 3 | // Computes the edit distance (Levenshtein Distance) between two strings. 4 | // 5 | // If either a or b is length 0, we must add/remove max(length(a), length(b)) 6 | // characters to have identical strings. 7 | // 8 | // If the last characters of a and b are the same, we recurse on a[:-1], b[:-1]. 9 | // 10 | // Otherwise we return 1 + min of the these three candidate operations: 11 | // 12 | // 1. Adding the last character of a -> a[:-1], b 13 | // 2. Removing the last character of a -> a, b[:-1] 14 | // 3. Swapping the last character of a -> a[:-1], b[:-1] 15 | // 16 | public int minDistance(String a, String b) { 17 | int[][] matrix = new int[a.length() + 1][b.length() + 1]; 18 | 19 | for (int i = 0; i < matrix.length; i++) { 20 | for (int j = 0; j < matrix[i].length; j++) { 21 | if (i == 0) { 22 | matrix[i][j] = j; 23 | } else if (j == 0) { 24 | matrix[i][j] = i; 25 | } else if (a.charAt(i - 1) == b.charAt(j - 1)) { 26 | matrix[i][j] = matrix[i - 1][j - 1]; 27 | } else { 28 | matrix[i][j] = 1 + min(matrix[i - 1][j], 29 | matrix[i][j - 1], 30 | matrix[i - 1][j - 1]); 31 | } 32 | } 33 | } 34 | 35 | return matrix[a.length()][b.length()]; 36 | } 37 | 38 | // 39 | // Returns the smallest of three integers. 40 | // 41 | public int min(int a, int b, int c) { 42 | return Math.min(a, Math.min(b, c)); 43 | } 44 | 45 | public static void main(String[] args) { 46 | System.out.println("Please run this solution on LeetCode."); 47 | System.out.println("https://leetcode.com/problems/edit-distance/"); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /leetcode/algorithms/edit-distance/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 4 | class Solution(object): 5 | def minDistance(self, a, b): 6 | """ 7 | Returns the edit distance between strings a and b. 8 | """ 9 | n = len(a) 10 | m = len(b) 11 | 12 | # If either string is empty, we need to add all characters from other 13 | # string. 14 | if n == 0 or m == 0: 15 | return max(n, m) 16 | 17 | # n x m matrix where each dp[i][j] represents the edit distance for 18 | # a[:i + 1] and b[:j + 1]. 19 | dp = [([0] * (m + 1)) for i in range(0, n + 1)] 20 | 21 | for i in range(0, n + 1): 22 | for j in range(0, m + 1): 23 | if i == 0: 24 | dp[i][j] = j 25 | elif j == 0: 26 | dp[i][j] = i 27 | elif a[i - 1] == b[j - 1]: 28 | # If the trailing characters are the same, we don't need to 29 | # perform an operation to bring these characters in sync. 30 | dp[i][j] = dp[i - 1][j - 1] 31 | else: 32 | dp[i][j] = 1 + \ 33 | min(dp[i - 1][j - 1], # Replace a[i] with b[j] 34 | dp[i][j - 1], # Add a[i] to b[:j] (Insert) 35 | dp[i - 1][j]) # Add b[j] to a[:i] (Delete) 36 | 37 | return dp[n][m] 38 | 39 | 40 | def main(): 41 | print('Please run this solution on LeetCode.') 42 | print('https://leetcode.com/problems/edit-distance/') 43 | 44 | if __name__ == '__main__': 45 | main() 46 | -------------------------------------------------------------------------------- /leetcode/algorithms/encode-string-with-shortest-length/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/contest/leetcode-weekly-contest-12/problems/encode-string-with-shortest-length/](https://leetcode.com/contest/leetcode-weekly-contest-12/problems/encode-string-with-shortest-length/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/encode-string-with-shortest-length/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 4 | class Solution(object): 5 | def encode(self, s): 6 | """Encodes a string with the shortest possible length in O(n^3) time. 7 | 8 | See problem description for encoding rules. Credit to Stefan Pochmann 9 | for finding optimal repeating prefix substring. See his original 10 | solution at https://discuss.leetcode.com/topic/71442/short-python. 11 | """ 12 | n = len(s) 13 | 14 | # Each dp[x] represents the shortest encoding for a substring x of s. 15 | dp = dict() 16 | return self.encodeUtil(s, dp) 17 | 18 | def encodeUtil(self, s, dp): 19 | """Calculates the shortest encoding for s. 20 | 21 | There are O(n^2) subproblems but each subproblem considers O(n) smaller 22 | subproblems so the overall runtime is O(n^3).""" 23 | n = len(s) 24 | if n < 5: 25 | # Cannot compress anything shorter than 5 characters. 26 | return s 27 | elif s in dp: 28 | return dp[s] 29 | 30 | # Encode the string raw by default. 31 | encoding = s 32 | 33 | # Encode the string as the shortest repeating substring if possible. 34 | i = (s + s).find(s, 1) 35 | 36 | # Check if a repeating substring exists and it is not s. 37 | if i != -1 and i < n: 38 | repeat = s[:i] 39 | count = n / len(repeat) 40 | encoding = '%d[%s]' % (count, self.encodeUtil(repeat, dp)) 41 | 42 | # Now consider all possible splits between chars 0 through n - 1. 43 | for i in range(1, n): 44 | left = self.encodeUtil(s[:i], dp) 45 | right = self.encodeUtil(s[i:], dp) 46 | if len(left) + len(right) < len(encoding): 47 | encoding = left + right 48 | 49 | dp[s] = encoding 50 | return encoding 51 | 52 | 53 | def main(): 54 | print('Please run this solution on LeetCode.') 55 | print('https://leetcode.com/contest/leetcode-weekly-contest-12/problems/encode-string-with-shortest-length/') # nopep8 56 | 57 | if __name__ == '__main__': 58 | main() 59 | -------------------------------------------------------------------------------- /leetcode/algorithms/flatten-binary-tree/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/flatten-binary-tree-to-linked-list/](https://leetcode.com/problems/flatten-binary-tree-to-linked-list/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/flatten-binary-tree/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 4 | class Solution(object): 5 | def flatten(self, root): 6 | """ 7 | Flattens the tree at the root node into a linked list. The problem 8 | statement depicts a pre-order flattening which we can do with an 9 | iterative traversal. 10 | 11 | :type root: TreeNode 12 | :rtype: None 13 | """ 14 | if root is None: 15 | return 16 | 17 | stack = [root] 18 | 19 | # The parent of the top node in the stack. This is the previous node 20 | # since we are doing a preorder traversal. 21 | parent = TreeNode(None) 22 | 23 | while len(stack) > 0: 24 | node = stack.pop() 25 | 26 | # Update previous/parent node with this node as the right child. 27 | parent.left = None 28 | parent.right = node 29 | parent = node 30 | 31 | if node.right is not None: 32 | stack.append(node.right) 33 | 34 | if node.left is not None: 35 | stack.append(node.left) 36 | 37 | 38 | def main(): 39 | print('Please run this solution on LeetCode.') 40 | print('https://leetcode.com/problems/flatten-binary-tree-to-linked-list/') 41 | 42 | if __name__ == '__main__': 43 | main() 44 | -------------------------------------------------------------------------------- /leetcode/algorithms/game-of-life/Makefile: -------------------------------------------------------------------------------- 1 | JAVA := java 2 | JAVAC := javac 3 | JAVACFLAGS := -Xlint:all 4 | 5 | default: clean build run 6 | 7 | build: 8 | $(JAVAC) $(JAVACFLAGS) Solution.java 9 | 10 | clean: 11 | $(RM) Solution.class 12 | 13 | run: 14 | $(JAVA) Solution 15 | -------------------------------------------------------------------------------- /leetcode/algorithms/game-of-life/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/game-of-life/](https://leetcode.com/problems/game-of-life/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/gas-station/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/gas-station/](https://leetcode.com/problems/gas-station/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/interleaving-string/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/interleaving-string/](https://leetcode.com/problems/interleaving-string/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/is-balanced/Makefile: -------------------------------------------------------------------------------- 1 | LIBS := ../libs 2 | JAVA := java 3 | JAVAC := javac 4 | JAVACFLAGS := -Xlint:all 5 | 6 | default: clean build run 7 | 8 | build: 9 | make -C $(LIBS) 10 | mv $(LIBS)/*.class . 11 | $(JAVAC) $(JAVACFLAGS) *.java 12 | 13 | clean: 14 | make -C $(LIBS) clean 15 | $(RM) *.class 16 | 17 | run: 18 | $(JAVA) Solution 19 | -------------------------------------------------------------------------------- /leetcode/algorithms/is-balanced/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/balanced-binary-tree/](https://leetcode.com/problems/balanced-binary-tree/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/is-balanced/Solution.java: -------------------------------------------------------------------------------- 1 | public class Solution { 2 | // 3 | // Checks if the tree rooted at this node is balanced. (If height of left and 4 | // right sub-tree do not differ in height by more than 1) 5 | // 6 | public boolean isBalanced(TreeNode root) { 7 | return isBalancedHeight(root) != -1; 8 | } 9 | 10 | // 11 | // Returns the height of the tree rooted at this node or -1 if the tree is 12 | // not balanced. 13 | // 14 | public int isBalancedHeight(TreeNode root) { 15 | if (root == null) { 16 | return 0; 17 | } 18 | 19 | // Check if left sub-tree is not balanced 20 | int leftHeight = isBalancedHeight(root.left); 21 | if (leftHeight == -1) { 22 | return -1; 23 | } 24 | 25 | // Check if right sub-tree is not balanced 26 | int rightHeight = isBalancedHeight(root.right); 27 | if (rightHeight == -1) { 28 | return -1; 29 | } 30 | 31 | // Check if left and right sub-tree have a height difference > 1 32 | if (Math.abs(leftHeight - rightHeight) > 1) { 33 | return -1; 34 | } 35 | 36 | // Return height of this tree 37 | return 1 + Math.max(leftHeight, rightHeight); 38 | } 39 | 40 | public static void main(String[] args) { 41 | System.out.println("Please run this solution on LeetCode."); 42 | System.out.println("https://leetcode.com/problems/balanced-binary-tree/"); 43 | } 44 | } -------------------------------------------------------------------------------- /leetcode/algorithms/k-pairs-with-smallest-sums/Makefile: -------------------------------------------------------------------------------- 1 | JAVA := java 2 | JAVAC := javac 3 | JAVACFLAGS := -Xlint:all 4 | 5 | default: clean build run 6 | 7 | build: 8 | $(JAVAC) $(JAVACFLAGS) Solution.java 9 | 10 | clean: 11 | $(RM) Solution.class 12 | 13 | run: 14 | $(JAVA) Solution 15 | -------------------------------------------------------------------------------- /leetcode/algorithms/k-pairs-with-smallest-sums/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/find-k-pairs-with-smallest-sums/](https://leetcode.com/problems/find-k-pairs-with-smallest-sums/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/kth-largest-element/Makefile: -------------------------------------------------------------------------------- 1 | JAVA := java 2 | JAVAC := javac 3 | JAVACFLAGS := -Xlint:all 4 | 5 | default: clean build run 6 | 7 | build: 8 | $(JAVAC) $(JAVACFLAGS) Solution.java 9 | 10 | clean: 11 | $(RM) Solution.class 12 | 13 | run: 14 | $(JAVA) Solution 2 15 | -------------------------------------------------------------------------------- /leetcode/algorithms/kth-largest-element/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/kth-largest-element-in-an-array/](https://leetcode.com/problems/kth-largest-element-in-an-array/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/kth-smallest-element-in-sorted-matrix/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/](https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/kth-smallest-element-in-sorted-matrix/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 4 | from heapq import * 5 | 6 | 7 | class Solution(object): 8 | def kthSmallest(self, matrix, k): 9 | """ 10 | Returns the kth smallest element in a matrix with rows and columns 11 | sorted in ascending order. This is an O(N + KlogN) algorithm. 12 | """ 13 | n = len(matrix) 14 | assert k >= 1 15 | assert k <= n**2 16 | 17 | # Min heap of tuples representing the (value, row, col) of potential 18 | # candidate cells. 19 | candidates = [(matrix[r][0], r, 0) for r in xrange(0, n)] 20 | heapify(candidates) 21 | 22 | # The inorder position of the next candidate we can pop from the heap. 23 | position = 1 24 | 25 | # In each iteration of the loop traverse to the right across the lowest 26 | # value cell. The next cell is always GTE to the current cell. 27 | while position < k: 28 | (value, r, c) = heappop(candidates) 29 | position += 1 30 | 31 | # If there is a cell to the right of the one we just popped, add it 32 | # to the heap. 33 | if c < n - 1: 34 | heappush(candidates, (matrix[r][c + 1], r, c + 1)) 35 | 36 | return heappop(candidates)[0] 37 | 38 | 39 | def main(): 40 | print('Please run this solution on LeetCode.') 41 | print('https://leetcode.com/problems/kth-smallest-element-in-a-sorted-matrix/') # nopep8 42 | 43 | if __name__ == '__main__': 44 | main() 45 | -------------------------------------------------------------------------------- /leetcode/algorithms/largest-rectangle-in-histogram/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/largest-rectangle-in-histogram/](https://leetcode.com/problems/largest-rectangle-in-histogram/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/lca-binary-tree/Makefile: -------------------------------------------------------------------------------- 1 | LIBS := ../libs 2 | JAVA := java 3 | JAVAC := javac 4 | JAVACFLAGS := -Xlint:all 5 | 6 | default: clean build run 7 | 8 | build: 9 | make -C $(LIBS) 10 | mv $(LIBS)/*.class . 11 | $(JAVAC) $(JAVACFLAGS) *.java 12 | 13 | clean: 14 | make -C $(LIBS) clean 15 | $(RM) *.class 16 | 17 | run: 18 | $(JAVA) Solution 19 | -------------------------------------------------------------------------------- /leetcode/algorithms/lca-binary-tree/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/lca-binary-tree/Solution.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | 4 | public class Solution { 5 | // 6 | // Finds the LCA of node p and q in the tree. Returns null if p or q is not in 7 | // the tree. 8 | // 9 | public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { 10 | List pPath = findPath(root, p); 11 | List qPath = findPath(root, q); 12 | int length = Math.min(pPath.size(), qPath.size()); 13 | for (int i = 0; i < length; i++) { 14 | if (pPath.get(i) != qPath.get(i)) { 15 | return pPath.get(i - 1); 16 | } 17 | } 18 | return pPath.get(length - 1); 19 | } 20 | 21 | // 22 | // Returns a path of nodes from root to target in the tree. The path is empty 23 | // if target is not in the tree. 24 | // 25 | public List findPath(TreeNode root, TreeNode target) { 26 | List path = new ArrayList<>(); 27 | findPathHelper(root, target, path); 28 | return path; 29 | } 30 | 31 | // 32 | // Populates the path list with nodes that represent the path from the root to 33 | // the target node. Returns a boolean indicating if the target was found in 34 | // the tree at the specified root. 35 | // 36 | public boolean findPathHelper(TreeNode root, TreeNode target, List path) { 37 | if (root == null) { 38 | return false; 39 | } 40 | path.add(root); 41 | if (root == target) { 42 | return true; 43 | } 44 | if (findPathHelper(root.left, target, path)) { 45 | return true; 46 | } else if (findPathHelper(root.right, target, path)) { 47 | return true; 48 | } 49 | path.remove(path.size() - 1); 50 | return false; 51 | } 52 | 53 | public static void main(String[] args) { 54 | System.out.println("Please run this solution on LeetCode."); 55 | System.out.println("https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/"); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /leetcode/algorithms/lexicographical-numbers/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /leetcode/algorithms/lexicographical-numbers/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/lexicographical-numbers/](https://leetcode.com/problems/lexicographical-numbers/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/lfu-cache/Makefile: -------------------------------------------------------------------------------- 1 | JAVA := java 2 | JAVAC := javac 3 | JAVACFLAGS := -Xlint:all 4 | 5 | default: clean build run 6 | 7 | build: 8 | $(JAVAC) $(JAVACFLAGS) *.java 9 | 10 | clean: 11 | $(RM) *.class 12 | 13 | run: 14 | $(JAVA) LFUCache 15 | -------------------------------------------------------------------------------- /leetcode/algorithms/lfu-cache/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/lfu-cache/](https://leetcode.com/problems/lfu-cache/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/libs/ListNode.java: -------------------------------------------------------------------------------- 1 | // 2 | // LeetCode ListNode class for local compilation. 3 | // 4 | class ListNode { 5 | public int val; 6 | 7 | public ListNode next; 8 | 9 | public ListNode(int val) { 10 | this.val = val; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /leetcode/algorithms/libs/Makefile: -------------------------------------------------------------------------------- 1 | JAVA := java 2 | JAVAC := javac 3 | JAVACFLAGS := -Xlint:all 4 | 5 | .SUFFIXES: .java .class 6 | .java.class: 7 | $(JAVAC) $(JAVACFLAGS) $*.java 8 | 9 | CLASSES = $(wildcard *.java) 10 | 11 | default: classes 12 | 13 | classes: $(CLASSES:.java=.class) 14 | 15 | clean: 16 | $(RM) *.class 17 | -------------------------------------------------------------------------------- /leetcode/algorithms/libs/Point.java: -------------------------------------------------------------------------------- 1 | public class Point { 2 | public int x; 3 | 4 | public int y; 5 | 6 | public Point() { 7 | x = 0; 8 | y = 0; 9 | } 10 | 11 | public Point(int x, int y) { 12 | this.x = x; 13 | this.y = y; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /leetcode/algorithms/libs/TreeNode.java: -------------------------------------------------------------------------------- 1 | public class TreeNode { 2 | public int val; 3 | 4 | public TreeNode left; 5 | 6 | public TreeNode right; 7 | 8 | public TreeNode(int val) { 9 | this.val = val; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /leetcode/algorithms/linked-list-cycle-ii/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/linked-list-cycle-ii/](https://leetcode.com/problems/linked-list-cycle-ii/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/linked-list-cycle-ii/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 4 | class Solution(object): 5 | def detectCycle(self, head): 6 | """ 7 | Given the head of a linked list finds and returns the node where a 8 | cycle begins. Uses O(1) space and O(N) time. 9 | 10 | Imagine the list is made up of two parts. The first part before the 11 | the cycle is of length K followed by cycle length N. If we place a slow 12 | and fast (double speed) pointer at the head of the list, the fast 13 | pointer will be N % K nodes into the cycle when the slow pointer 14 | reaches the start of the cycle. 15 | 16 | This means that the slow pointer is N % K nodes behind the fast pointer 17 | and N - (N % K) nodes ahead of it. Thus the pointers will collide 18 | N - (N % K) nodes into the cycle. 19 | 20 | When they collide, we place one of the pointers back to the head and 21 | increment both pointers at normal speed. They will collide at the 22 | start of the cycle. This is because it will take the pointer now at 23 | the head K turns to get to the start of the cycle at which point the 24 | other pointer will be at position N % (N - N % K + K) = 0 in the cycle 25 | as well. 26 | """ 27 | slow = head 28 | fast = head 29 | 30 | # Move pointers until we reach end of cycle or pointers collide. 31 | while fast is not None and fast.next is not None: 32 | slow = slow.next 33 | fast = fast.next.next 34 | if slow == fast: 35 | break 36 | 37 | # Take care of case with no cycle. 38 | if fast is None or fast.next is None: 39 | return None 40 | 41 | # Now move one pointer back to head and iterate one node at a time. 42 | slow = head 43 | while slow != fast: 44 | slow = slow.next 45 | fast = fast.next 46 | 47 | return slow 48 | 49 | 50 | def main(): 51 | print('Please run this solution on LeetCode.') 52 | print('https://leetcode.com/problems/linked-list-cycle-ii/') 53 | 54 | if __name__ == '__main__': 55 | main() 56 | -------------------------------------------------------------------------------- /leetcode/algorithms/longest-valid-parenthesis/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/longest-valid-parentheses/](https://leetcode.com/problems/longest-valid-parentheses/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/majority-element-ii/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/majority-element-ii/](https://leetcode.com/problems/majority-element-ii/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/max-points-on-a-line/Makefile: -------------------------------------------------------------------------------- 1 | LIBS := ../libs 2 | JAVA := java 3 | JAVAC := javac 4 | JAVACFLAGS := -Xlint:all 5 | 6 | default: clean build run 7 | 8 | build: 9 | make -C $(LIBS) 10 | mv $(LIBS)/*.class . 11 | $(JAVAC) $(JAVACFLAGS) *.java 12 | 13 | clean: 14 | make -C $(LIBS) clean 15 | $(RM) *.class 16 | 17 | run: 18 | $(JAVA) -ea Solution 19 | -------------------------------------------------------------------------------- /leetcode/algorithms/max-points-on-a-line/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/max-points-on-a-line/](https://leetcode.com/problems/max-points-on-a-line/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/maximum-gap/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/maximum-gap/](https://leetcode.com/problems/maximum-gap/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/median-of-two-sorted-arrays/Makefile: -------------------------------------------------------------------------------- 1 | JAVA := java 2 | JAVAC := javac 3 | JAVACFLAGS := -Xlint:all 4 | 5 | default: clean build run 6 | 7 | build: 8 | $(JAVAC) $(JAVACFLAGS) Solution.java 9 | 10 | clean: 11 | $(RM) Solution.class 12 | 13 | run: 14 | $(JAVA) Solution 15 | -------------------------------------------------------------------------------- /leetcode/algorithms/median-of-two-sorted-arrays/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/median-of-two-sorted-arrays/](https://leetcode.com/problems/median-of-two-sorted-arrays/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/mini-parser/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/mini-parser/](https://leetcode.com/problems/mini-parser/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/minimum-height-tree/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /leetcode/algorithms/minimum-height-tree/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/minimum-height-trees/](https://leetcode.com/problems/minimum-height-trees/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/minimum-window-substring/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/minimum-window-substring/](https://leetcode.com/problems/minimum-window-substring/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/n-queens-ii/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 8 14 | -------------------------------------------------------------------------------- /leetcode/algorithms/n-queens-ii/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/n-queens-ii/](https://leetcode.com/problems/n-queens-ii/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/n-queens-ii/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // 6 | // Tracks row, diagonal, and anit-diagonal Queen attacking state of a board. 7 | // 8 | class State { 9 | private: 10 | std::vector cols; 11 | 12 | std::vector diags; 13 | 14 | std::vector anti; 15 | 16 | size_t n; 17 | 18 | public: 19 | explicit State(size_t n) : cols(n), diags(2 * n), anti(2 * n), n(n) { 20 | } 21 | 22 | // 23 | // Returns a bool indicating if the (row, col) cell is under attack by an 24 | // existing Queen. 25 | // 26 | inline bool isValid(size_t row, size_t col) { 27 | if (cols[col] || diags[row - col + n] || anti[row + col]) { 28 | return false; 29 | } 30 | return true; 31 | } 32 | 33 | // 34 | // Updates the state by setting a Queen at the specified (row, col) cell. 35 | // 36 | inline void set(size_t row, size_t col) { 37 | cols[col] = true; 38 | diags[row - col + n] = true; 39 | anti[row + col] = true; 40 | } 41 | 42 | // 43 | // Updates the state by erasing a Queen from the specified (row, col) cell. 44 | // 45 | inline void erase(size_t row, size_t col) { 46 | cols[col] = false; 47 | diags[row - col + n] = false; 48 | anti[row + col] = false; 49 | } 50 | }; 51 | 52 | class Solution { 53 | public: 54 | int totalNQueens(State& state, size_t row, size_t n) { // NOLINT 55 | if (row == n) { 56 | return 1; // End of algorithm... 57 | } 58 | uint64_t total = 0; 59 | for (size_t col = 0; col < n; col++) { 60 | // Check if we can place a Queen here... 61 | if (!state.isValid(row, col)) { 62 | continue; 63 | } 64 | // Place Queen here and DFS... 65 | state.set(row, col); 66 | total += totalNQueens(state, row + 1, n); 67 | state.erase(row, col); 68 | } 69 | return total; 70 | } 71 | 72 | int totalNQueens(int n) { 73 | State state(n); 74 | return totalNQueens(state, 0, n); 75 | } 76 | }; 77 | 78 | int main(int argc, char* argv[]) { 79 | if (argc < 2) { 80 | std::cerr << "Please specify N." << std::endl; 81 | return 1; 82 | } 83 | int N = std::stoi(argv[1]); 84 | Solution solution; 85 | std::cout << solution.totalNQueens(N) << std::endl; 86 | return 0; 87 | } 88 | -------------------------------------------------------------------------------- /leetcode/algorithms/non-overlapping-intervals/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/non-overlapping-intervals/](https://leetcode.com/problems/non-overlapping-intervals/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/non-overlapping-intervals/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 4 | class Solution(object): 5 | def eraseOverlapIntervals(self, intervals): 6 | """ 7 | Proof of Correctness: 8 | http://lonati.di.unimi.it/algo/0910/lab/kowalski6.pdf 9 | 10 | :type intervals: List[Interval] 11 | :rtype: int 12 | """ 13 | n = len(intervals) 14 | if n < 2: 15 | return 0 16 | 17 | # Sort intervals by (1) end point in increasing order and (2) start 18 | # point in decreasing order. 19 | intervals = list(sorted(intervals, 20 | key=lambda itr: (itr.end, -itr.start))) 21 | 22 | erase = 0 23 | end = intervals[0].end 24 | for i in range(1, n): 25 | itr = intervals[i] 26 | if itr.start >= end: 27 | end = itr.end 28 | else: 29 | erase += 1 30 | 31 | return erase 32 | 33 | 34 | def main(): 35 | print('Please run this solution on LeetCode.') 36 | print('https://leetcode.com/problems/non-overlapping-intervals/') 37 | 38 | if __name__ == '__main__': 39 | main() 40 | -------------------------------------------------------------------------------- /leetcode/algorithms/palindrome-linked-list/Makefile: -------------------------------------------------------------------------------- 1 | LIBS := ../libs 2 | JAVA := java 3 | JAVAC := javac 4 | JAVACFLAGS := -Xlint:all 5 | 6 | default: clean build run 7 | 8 | build: 9 | make -C $(LIBS) 10 | mv $(LIBS)/*.class . 11 | $(JAVAC) $(JAVACFLAGS) *.java 12 | 13 | clean: 14 | make -C $(LIBS) clean 15 | $(RM) *.class 16 | 17 | run: 18 | $(JAVA) Solution 19 | -------------------------------------------------------------------------------- /leetcode/algorithms/palindrome-linked-list/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/palindrome-linked-list/](https://leetcode.com/problems/palindrome-linked-list/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/palindrome-pairs/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/palindrome-pairs/](https://leetcode.com/problems/palindrome-pairs/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/permutation-sequence/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /leetcode/algorithms/permutation-sequence/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/permutation-sequence/](https://leetcode.com/problems/permutation-sequence/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/permutations-ii/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /leetcode/algorithms/permutations-ii/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/permutations-ii/](https://leetcode.com/problems/permutations-ii/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/range-sum-query-mutable/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /leetcode/algorithms/range-sum-query-mutable/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/range-sum-query-mutable/](https://leetcode.com/problems/range-sum-query-mutable/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/recover-binary-tree/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/recover-binary-search-tree/](https://leetcode.com/problems/recover-binary-search-tree/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/rectangle-area/Makefile: -------------------------------------------------------------------------------- 1 | LIBS := ../libs 2 | JAVA := java 3 | JAVAC := javac 4 | JAVACFLAGS := -Xlint:all 5 | 6 | default: clean build run 7 | 8 | build: 9 | make -C $(LIBS) 10 | mv $(LIBS)/*.class . 11 | $(JAVAC) $(JAVACFLAGS) *.java 12 | 13 | clean: 14 | make -C $(LIBS) clean 15 | $(RM) *.class 16 | 17 | run: 18 | $(JAVA) Solution 19 | -------------------------------------------------------------------------------- /leetcode/algorithms/rectangle-area/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/rectangle-area/](https://leetcode.com/problems/rectangle-area/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/rectangle-area/Solution.java: -------------------------------------------------------------------------------- 1 | public class Solution { 2 | // 3 | // Computes the union area of two rectangles. 4 | // 5 | public int computeArea(int A, int B, int C, int D, int E, int F, int G, int H) { 6 | int areaX = (D - B) * (C - A); 7 | int areaY = (H - F) * (G - E); 8 | int total = areaX + areaY; 9 | int overlap = computeOverlap(A, B, C, D, E, F, G, H); 10 | return total - overlap; 11 | } 12 | 13 | // 14 | // Computes the intersection are of two rectangles. 15 | // 16 | public int computeOverlap(int A, int B, int C, int D, int E, int F, int G, int H) { 17 | // Check if there is no horizontal overlap. 18 | if (A > G || C < E) { 19 | return 0; 20 | } 21 | 22 | // Check if there is no vertical overlap. 23 | if (B > H || D < F) { 24 | return 0; 25 | } 26 | 27 | // Get width and height of square X. (Chosen arbitrarily) 28 | int width = G - E; 29 | int height = H - F; 30 | 31 | // Find the width and height of the overlap by subtracting the distance 32 | // between the edges of rectangle X and edges of rectangle Y for edges of Y 33 | // that are inside rectangle X. 34 | width -= (Math.max(0, A - E) + Math.max(0, G - C)); 35 | height -= (Math.max(0, H - D) + Math.max(0, B - F)); 36 | 37 | return width * height; 38 | } 39 | 40 | public static void main(String[] args) { 41 | System.out.println("Please run this solution on LeetCode."); 42 | System.out.println("https://leetcode.com/problems/rectangle-area/"); 43 | } 44 | } -------------------------------------------------------------------------------- /leetcode/algorithms/regular-expression-matching/Makefile: -------------------------------------------------------------------------------- 1 | JAVA := java 2 | JAVAC := javac 3 | JAVACFLAGS := -Xlint:all 4 | 5 | default: clean build run 6 | 7 | build: 8 | $(JAVAC) $(JAVACFLAGS) Solution.java 9 | 10 | clean: 11 | $(RM) Solution.class 12 | 13 | run: 14 | $(JAVA) -ea Solution 15 | -------------------------------------------------------------------------------- /leetcode/algorithms/regular-expression-matching/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/regular-expression-matching/](https://leetcode.com/problems/regular-expression-matching/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/remove-duplicates-from-sorted-array-ii/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/remove-duplicates-from-sorted-array-ii/](https://leetcode.com/problems/remove-duplicates-from-sorted-array-ii/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/remove-k-digits/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/contest/5/problems/remove-k-digits/](https://leetcode.com/contest/5/problems/remove-k-digits/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/remove-k-digits/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 4 | class Solution(object): 5 | def _min(self, number, i, length): 6 | """ 7 | Returns the index of the smallest digit in the first length characters 8 | starting at i. 9 | """ 10 | n = len(number) 11 | assert i >= 0 12 | assert i < n 13 | index = i 14 | for j in range(i + 1, min(n, i + length)): 15 | if number[j] < number[index]: 16 | index = j 17 | return index 18 | 19 | def _removeKdigits(self, number, i, k): 20 | """ 21 | Returns the largest possible number by removing k digits from 22 | number[i:]. 23 | """ 24 | n = len(number) 25 | assert i >= 0 26 | assert i < n 27 | 28 | if k == 0: 29 | return number[i:] 30 | elif k >= n - i: 31 | # Delete all remaining digits. 32 | return '' 33 | 34 | # Since at most K digits can re removed from the start of the number, 35 | # the first digit in the result must be in the first K + 1 digits. Find 36 | # the smallest digit in the first K + 1 digits to keep as the first 37 | # digit in the result. 38 | j = self._min(number, i, k + 1) 39 | 40 | # Count how many number between i (inclusive) and j (exclusive) we are 41 | # deleting. 42 | deleting = j - i 43 | 44 | # Continue looking if we have not reached the end of the number yet. 45 | if j < n - 1: 46 | return number[j] + self._removeKdigits(number, j + 1, k - deleting) 47 | return number[j] 48 | 49 | def removeKdigits(self, number, k): 50 | n = len(number) 51 | if n == 0 or k == n: 52 | # Number is empty or can be made empty by removing all digits. 53 | return '0' 54 | elif k == 0: 55 | return number 56 | return str(int(self._removeKdigits(number, 0, k))) 57 | 58 | 59 | def main(): 60 | print('Please run this solution on LeetCode.') 61 | print('https://leetcode.com/contest/5/problems/remove-k-digits/') 62 | 63 | if __name__ == '__main__': 64 | main() 65 | -------------------------------------------------------------------------------- /leetcode/algorithms/reverse-nodes-k-group/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/reverse-nodes-in-k-group/](https://leetcode.com/problems/reverse-nodes-in-k-group/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/reverse-nodes-k-group/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 4 | class Solution(object): 5 | def reverse(self, head, n): 6 | """ 7 | Reverses the first n nodes of the list starting at the specified head 8 | node. Returns a tuple (a, b, c) where a and b are the start and end of 9 | the reversed list. c is the length of the reversed portion of the list. 10 | """ 11 | assert n > 0 12 | assert head is not None 13 | 14 | tail = head 15 | current = head.next 16 | length = n 17 | n -= 1 18 | 19 | # Reverse the list by going through it in forward order and prepending 20 | # each node to the front. 21 | while n > 0 and current is not None: 22 | next = current.next 23 | current.next = head 24 | head = current 25 | current = next 26 | n -= 1 27 | 28 | # Ensure the tail of the reversed list points to the next element. 29 | tail.next = current 30 | return (head, tail, length - n) 31 | 32 | def reverseKGroup(self, head, k): 33 | """ 34 | Reverses the list starting at the head node k nodes at a time. If the 35 | list length is not a multiple of k the trailing nodes at the end must 36 | remain in their original order. 37 | """ 38 | sentinel = ListNode(None) 39 | sentinel.next = head 40 | current = sentinel 41 | 42 | while current is not None and current.next is not None: 43 | sublist = self.reverse(current.next, k) 44 | # Check if this is a trailing list with less than k nodes. 45 | if sublist[2] != k: 46 | # Reverse the list again to bring it back into original order. 47 | sublist = self.reverse(sublist[0], k) 48 | current.next = sublist[0] 49 | current = sublist[1] 50 | 51 | return sentinel.next 52 | 53 | 54 | def main(): 55 | print('Tests pass!') 56 | print('Please run this solution on LeetCode.') 57 | print('https://leetcode.com/problems/reverse-nodes-in-k-group/') 58 | 59 | 60 | if __name__ == "__main__": 61 | main() 62 | -------------------------------------------------------------------------------- /leetcode/algorithms/reverse-words-in-a-string/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /leetcode/algorithms/reverse-words-in-a-string/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/reverse-words-in-a-string/](https://leetcode.com/problems/reverse-words-in-a-string/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/rotate-image/Makefile: -------------------------------------------------------------------------------- 1 | JAVA := java 2 | JAVAC := javac 3 | JAVACFLAGS := -Xlint:all 4 | 5 | default: clean build run 6 | 7 | build: 8 | $(JAVAC) $(JAVACFLAGS) Solution.java 9 | 10 | clean: 11 | $(RM) Solution.class 12 | 13 | run: 14 | $(JAVA) Solution 15 | -------------------------------------------------------------------------------- /leetcode/algorithms/rotate-image/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/rotate-image/](https://leetcode.com/problems/rotate-image/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/rotate-image/Solution.java: -------------------------------------------------------------------------------- 1 | public class Solution { 2 | // 3 | // Rotates the matrix 90 degrees clockwise. 4 | // 5 | // The idea is that for an NxN matrix, if we wish to rotate point (x, y) 90 6 | // degrees clockwise, we need to move 4 the following 4 points around the 7 | // matrix. 8 | // 9 | // (x, y), (n - 1 - y, r), (n - 1 - x, n - 1 - y), (y, n - 1 - r) 10 | // 11 | // We apply this rotation for all points by going through (row ... n - 1 - row) 12 | // points in the first n / 2 rows. 13 | // 14 | // 15 | public void rotate(int[][] matrix) { 16 | if (matrix == null || matrix.length < 2) { 17 | return; 18 | } 19 | int n = matrix.length; 20 | for (int layer = 0; layer < n / 2; layer++) { 21 | // Important to avoid last point in each layer! That's because the last 22 | // point on this side of the top side of the square is really the first 23 | // point on the right side where the first point on the top will be moved 24 | // to. 25 | for (int col = layer; col < n - layer - 1; col++) { 26 | int here = matrix[layer][col]; 27 | matrix[layer][col] = matrix[n - 1 - col][layer]; 28 | matrix[n - 1 - col][layer] = matrix[n - 1 - layer][n - 1 - col]; 29 | matrix[n - 1 - layer][n - 1 - col] = matrix[col][n - 1 - layer]; 30 | matrix[col][n - 1 - layer] = here; 31 | } 32 | } 33 | } 34 | 35 | public static void main(String[] args) { 36 | System.out.println("Please run this solution on LeetCode."); 37 | System.out.println("https://leetcode.com/problems/rotate-image/"); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /leetcode/algorithms/set-matrix-zeroes/Makefile: -------------------------------------------------------------------------------- 1 | JAVA := java 2 | JAVAC := javac 3 | JAVACFLAGS := -Xlint:all 4 | 5 | default: clean build run 6 | 7 | build: 8 | $(JAVAC) $(JAVACFLAGS) Solution.java 9 | 10 | clean: 11 | $(RM) Solution.class 12 | 13 | run: 14 | $(JAVA) Solution 15 | -------------------------------------------------------------------------------- /leetcode/algorithms/set-matrix-zeroes/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/set-matrix-zeroes/](https://leetcode.com/problems/set-matrix-zeroes/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/set-matrix-zeroes/Solution.java: -------------------------------------------------------------------------------- 1 | import java.util.Arrays; 2 | import java.util.Random; 3 | 4 | public class Solution { 5 | public void setZeroes(int[][] matrix) { 6 | // Check for invalid matrix... 7 | if (matrix == null || matrix.length == 0) { 8 | return; 9 | } 10 | 11 | // Track columns and rows with 0's... 12 | boolean[] rows = new boolean[matrix.length]; 13 | boolean[] cols = new boolean[matrix[0].length]; 14 | 15 | // Find columns and rows with 0's... 16 | for (int r = 0; r < matrix.length; r++) { 17 | for (int c = 0; c < matrix[r].length; c++) { 18 | if (matrix[r][c] == 0) { 19 | rows[r] = true; 20 | cols[c] = true; 21 | } 22 | } 23 | } 24 | 25 | // Fill columns with 0's... 26 | for (int r = 0; r < rows.length; r++) { 27 | if (rows[r]) { 28 | Arrays.fill(matrix[r], 0); 29 | } 30 | } 31 | 32 | // Fill rows with 0's... 33 | for (int c = 0; c < cols.length; c++) { 34 | if (cols[c]) { 35 | for (int r = 0; r < rows.length; r++) { 36 | matrix[r][c] = 0; 37 | } 38 | } 39 | } 40 | } 41 | 42 | public static void main(String[] args) { 43 | System.out.println("Please run this solution on LeetCode."); 44 | System.out.println("https://leetcode.com/problems/set-matrix-zeroes/"); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /leetcode/algorithms/shortest-palindrome/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /leetcode/algorithms/shortest-palindrome/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/shortest-palindrome/](https://leetcode.com/problems/shortest-palindrome/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/skyline/Makefile: -------------------------------------------------------------------------------- 1 | JAVA := java 2 | JAVAC := javac 3 | JAVACFLAGS := -Xlint:all 4 | 5 | default: clean build run 6 | 7 | build: 8 | $(JAVAC) $(JAVACFLAGS) Solution.java 9 | 10 | clean: 11 | $(RM) Solution.class 12 | 13 | run: 14 | $(JAVA) -ea Solution 15 | -------------------------------------------------------------------------------- /leetcode/algorithms/skyline/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/the-skyline-problem/](https://leetcode.com/problems/the-skyline-problem/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/sliding-window-maximum/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/sliding-window-maximum/](https://leetcode.com/problems/sliding-window-maximum/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/sorted-array-to-bst/Makefile: -------------------------------------------------------------------------------- 1 | LIBS := ../libs 2 | JAVA := java 3 | JAVAC := javac 4 | JAVACFLAGS := -Xlint:all 5 | 6 | default: clean build run 7 | 8 | build: 9 | make -C $(LIBS) 10 | mv $(LIBS)/*.class . 11 | $(JAVAC) $(JAVACFLAGS) *.java 12 | 13 | clean: 14 | make -C $(LIBS) clean 15 | $(RM) *.class 16 | 17 | run: 18 | $(JAVA) Solution 19 | -------------------------------------------------------------------------------- /leetcode/algorithms/sorted-array-to-bst/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/](https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/sorted-array-to-bst/Solution.java: -------------------------------------------------------------------------------- 1 | public class Solution { 2 | // 3 | // Converts a sorted array to a balanced BST. 4 | // 5 | public TreeNode sortedArrayToBST(int[] array) { 6 | return sortedArrayToBST(array, 0, array.length - 1); 7 | } 8 | 9 | // 10 | // Converts sorted array array[lo] ... array[hi] to a balanced BST. 11 | // 12 | public TreeNode sortedArrayToBST(int[] array, int lo, int hi) { 13 | if (lo == hi) { 14 | return new TreeNode(array[lo]); 15 | } else if (hi < lo) { 16 | return null; 17 | } 18 | 19 | int mid = lo + (hi - lo) / 2; 20 | TreeNode node = new TreeNode(array[mid]); 21 | node.left = sortedArrayToBST(array, lo, mid - 1); 22 | node.right = sortedArrayToBST(array, mid + 1, hi); 23 | return node; 24 | } 25 | 26 | public static void main(String[] args) { 27 | System.out.println("Please run this solution on LeetCode."); 28 | System.out.println("https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/"); 29 | } 30 | } -------------------------------------------------------------------------------- /leetcode/algorithms/spiral-matrix/Makefile: -------------------------------------------------------------------------------- 1 | LIBS := ../libs 2 | JAVA := java 3 | JAVAC := javac 4 | JAVACFLAGS := -Xlint:all 5 | 6 | default: clean build run 7 | 8 | build: 9 | make -C $(LIBS) 10 | mv $(LIBS)/*.class . 11 | $(JAVAC) $(JAVACFLAGS) *.java 12 | 13 | clean: 14 | make -C $(LIBS) clean 15 | $(RM) *.class 16 | 17 | run: 18 | $(JAVA) -ea Solution 19 | -------------------------------------------------------------------------------- /leetcode/algorithms/spiral-matrix/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/rectangle-area/](https://leetcode.com/problems/rectangle-area/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/spiral-matrix/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 4 | class Solution(object): 5 | def spiralOrder(self, matrix): 6 | """ 7 | Returns the clockwise spiral order traversal of the matrix starting at 8 | (0, 0). Modifies the matrix to contain all None values. 9 | 10 | :type matrix: List[List[int]] 11 | :rtype: List[int] 12 | """ 13 | if len(matrix) == 0 or len(matrix[0]) == 0: 14 | return [] 15 | 16 | # Size of the matrix. 17 | n = len(matrix) 18 | m = len(matrix[0]) 19 | 20 | # Current row and column that we are on. 21 | r = 0 22 | c = 0 23 | 24 | # The delta values to get the next row and column. 25 | dr = 0 26 | dc = 1 27 | 28 | # The resulting spiral order and next insertion index. 29 | spiral = [0] * (n * m) 30 | i = 0 31 | 32 | for i in range(0, n * m): 33 | spiral[i] = matrix[r][c] 34 | matrix[r][c] = None # Mark this cell as visited 35 | i += 1 36 | 37 | # Check if the current delta will result in revisting a cell. 38 | nextr = (r + dr) % n 39 | nextc = (c + dc) % m 40 | if matrix[nextr][nextc] is None: 41 | dr, dc = dc, -dr # Turn right. 42 | 43 | # Go to next cell. 44 | r += dr 45 | c += dc 46 | 47 | return spiral 48 | 49 | 50 | def main(): 51 | print('Please run this solution on LeetCode.') 52 | print('https://leetcode.com/problems/spiral-matrix/') 53 | 54 | if __name__ == '__main__': 55 | main() 56 | -------------------------------------------------------------------------------- /leetcode/algorithms/sqrt/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/sqrtx/](https://leetcode.com/problems/sqrtx/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/sqrt/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 4 | class Solution(object): 5 | def mySqrt(self, x): 6 | assert x >= 0 7 | if x < 2: 8 | # Take care of base cases 0 and 1. 9 | return x 10 | 11 | lo = 1 12 | hi = x - 1 13 | root = lo 14 | 15 | # Use binary search to find largest root such that root^2 <= x 16 | while lo <= hi: 17 | mid = lo + int((hi - lo) / 2) 18 | square = mid**2 19 | if square == x: 20 | # Found exact match. 21 | return mid 22 | elif square <= x: 23 | # Found a square root candidate. Continue for searchig a larger 24 | # candidate. 25 | root = mid 26 | lo = mid + 1 27 | else: 28 | # Square is too large. Continue looking for smaller candidates. 29 | hi = mid - 1 30 | 31 | return root 32 | 33 | 34 | def main(): 35 | print('Please run this solution on LeetCode.') 36 | print('https://leetcode.com/problems/sqrtx/') 37 | 38 | if __name__ == '__main__': 39 | main() 40 | -------------------------------------------------------------------------------- /leetcode/algorithms/stock-profit-iii/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/stock-profit-iii/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 4 | class Solution(object): 5 | def maxProfit(self, prices): 6 | """ 7 | Finds the maximum profit that can be achieved with at most two 8 | non-overlapping transactions. The problem can be split into an FSM with 9 | 4 states. 10 | 11 | S0 = Began first transaction (Bought) 12 | S1 = Ended first transaction (Sold) 13 | S2 = Began second transaction (Bought) 14 | S3 = Ended second transaction (Sold) 15 | """ 16 | # No way to make a profit without at least two days of history. 17 | if len(prices) < 2: 18 | return 0 19 | 20 | # Init S0 and S2 with the negative of the highest price. This is the 21 | # lowest possible drawdown with an optimal strategy. 22 | topPrice = max(prices) 23 | state = [- topPrice, 0, - topPrice, 0] 24 | 25 | for p in prices: 26 | nextState = list(state) 27 | 28 | # Either stay at this current state or buy at a lower price if 29 | # possible. 30 | nextState[0] = max(state[0], - p) 31 | 32 | # Stay at the current state or sell the stock we bought in S0 at a 33 | # higher price. 34 | nextState[1] = max(state[1], state[0] + p) 35 | 36 | # If we have a positive balance after completing the first 37 | # transaction, it makes sense to begin the second. There's no 38 | # reason to begin the second transaction if the first transaction 39 | # is in a losing position because we might be able to recoupe 40 | # losses by selling at a future price with may be higher. 41 | if state[1] > 0: 42 | nextState[2] = max(state[2], state[1] - p) 43 | 44 | # Stay at the current state for the second transaction or sell at a 45 | # higher price. 46 | nextState[3] = max(state[3], state[2] + p) 47 | 48 | state = nextState 49 | 50 | return max(state[1], state[3]) 51 | 52 | 53 | def main(): 54 | print('Please run this solution on LeetCode.') 55 | print('https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/') 56 | 57 | if __name__ == '__main__': 58 | main() 59 | -------------------------------------------------------------------------------- /leetcode/algorithms/stock-profit-iv/Makefile: -------------------------------------------------------------------------------- 1 | JAVA := java 2 | JAVAC := javac 3 | JAVACFLAGS := -Xlint:all 4 | 5 | default: clean build run 6 | 7 | build: 8 | $(JAVAC) $(JAVACFLAGS) Solution.java 9 | 10 | clean: 11 | $(RM) Solution.class 12 | 13 | run: 14 | $(JAVA) Solution 15 | -------------------------------------------------------------------------------- /leetcode/algorithms/stock-profit-iv/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/subsets-ii/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++11 -Wall -o out 3 | 4 | default: build run 5 | 6 | build: 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /leetcode/algorithms/subsets-ii/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/subsets-ii/](https://leetcode.com/problems/subsets-ii/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/substring-concat-all-words/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/substring-with-concatenation-of-all-words/](https://leetcode.com/problems/substring-with-concatenation-of-all-words/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/sudoku-solver/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/sudoku-solver/](https://leetcode.com/problems/sudoku-solver/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/unique-substrings-wraparound-string/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/unique-substrings-in-wraparound-string/](https://leetcode.com/problems/unique-substrings-in-wraparound-string/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/unique-substrings-wraparound-string/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 4 | class Solution(object): 5 | def alpha(self, c): 6 | """Returns the index of char c in the alphabet.""" 7 | return ord(c) - ord('a') 8 | 9 | def findSubstringInWraproundString(self, p): 10 | """Counts the unique substrings of p in the infinite wraparound string. 11 | 12 | This is an O(n) time and space DP algorithm. 13 | 14 | Args: 15 | p (str): The string whos substrings we are considering. 16 | 17 | Returns: 18 | (int) 19 | """ 20 | n = len(p) 21 | if n == 0 or n == 1: 22 | return n 23 | 24 | # Create a DP array that tracks the length of the longest alphabetic 25 | # substring starting at char c we have considered thus far. 26 | chars = set(p) 27 | dp = {c: 0 for c in chars} 28 | 29 | i = 0 30 | count = 0 31 | 32 | # Loop through p and find chunks of alphabetic substrings. 33 | while i < n: 34 | # Find the endpoint of the current alphabetic window substring 35 | # starting at index i. 36 | j = i + 1 37 | while j < n and \ 38 | self.alpha(p[j]) == (self.alpha(p[j - 1]) + 1) % 26: 39 | j += 1 40 | 41 | # Treat each k as a substring starting point. 42 | for k in xrange(i, j): 43 | c = p[k] 44 | length = j - k 45 | 46 | # We may have counted substrings starting with c before so 47 | # count only the longer ones we have not considered yet. 48 | endpoints = max(0, length - dp[c]) 49 | count += endpoints 50 | 51 | # Update the longest substring starting with c we have counted. 52 | dp[c] = max(dp[c], length) 53 | 54 | # Start looking for next alphabetic window at j. 55 | i = j 56 | 57 | return count 58 | 59 | 60 | def main(): 61 | print('Please run this solution on LeetCode.') 62 | print('https://leetcode.com/problems/unique-substrings-in-wraparound-string/') # nopep8 63 | 64 | if __name__ == '__main__': 65 | main() 66 | -------------------------------------------------------------------------------- /leetcode/algorithms/validate-bst/Makefile: -------------------------------------------------------------------------------- 1 | LIBS := ../libs 2 | JAVA := java 3 | JAVAC := javac 4 | JAVACFLAGS := -Xlint:all 5 | 6 | default: clean build run 7 | 8 | build: 9 | make -C $(LIBS) 10 | mv $(LIBS)/*.class . 11 | $(JAVAC) $(JAVACFLAGS) *.java 12 | 13 | clean: 14 | make -C $(LIBS) clean 15 | $(RM) *.class 16 | 17 | run: 18 | $(JAVA) Solution 19 | -------------------------------------------------------------------------------- /leetcode/algorithms/validate-bst/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/validate-binary-search-tree/](https://leetcode.com/problems/validate-binary-search-tree/) 4 | -------------------------------------------------------------------------------- /leetcode/algorithms/validate-bst/Solution.java: -------------------------------------------------------------------------------- 1 | import java.util.Stack; 2 | 3 | public class Solution { 4 | // 5 | // This is a BFS algorithms that checks if the tree rooted at the given node 6 | // is a valid BST. 7 | // 8 | public boolean isValidBST(TreeNode root) { 9 | if (root == null) { 10 | return true; 11 | } 12 | Integer prev = null; 13 | TreeNode curr = root; 14 | Stack stack = new Stack<>(); 15 | while (!stack.isEmpty() || curr != null) { 16 | // Continue all the way down the left... 17 | while (curr != null) { 18 | stack.push(curr); 19 | curr = curr.left; 20 | } 21 | curr = stack.pop(); 22 | // Check if the current node violates BFS rule... 23 | if (prev != null && curr.val <= prev) { 24 | return false; 25 | } 26 | // Take the right branch... 27 | prev = curr.val; // The prev is now the value at the current node... 28 | curr = curr.right; // Might be null but ok if stack is not empty... 29 | } 30 | return true; 31 | } 32 | 33 | public static void main(String[] args) { 34 | System.out.println("Please run this solution on LeetCode."); 35 | System.out.println("https://leetcode.com/problems/validate-binary-search-tree/"); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /leetcode/algorithms/wiggle-subsequence/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/wiggle-subsequence/](https://leetcode.com/problems/wiggle-subsequence/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/wiggle-subsequence/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 4 | class Solution(object): 5 | def wiggleMaxLength(self, values): 6 | """ 7 | Returns the maximum length of a wiggle subsequence. The problem boils 8 | down to finding the number of min/max inflection points in the 9 | sequence. For example, if we are looking for an "up" wiggle in the 10 | sequence it makes sense to go as high up as we can to increase the set 11 | of numbers that will allow us to come back in a "down" wiggle. Similar 12 | logic holds when going "down" the wiggle. 13 | 14 | LeetCode has an excellent article about this problem: 15 | https://leetcode.com/articles/wiggle-subsequence/ 16 | 17 | :type values: List[int] 18 | :rtype int 19 | """ 20 | n = len(values) 21 | if n < 2: 22 | return n 23 | 24 | i = 0 25 | 26 | # Find the starting direction of the wiggle sequence. 27 | while i < n - 1: 28 | if values[i] != values[i + 1]: 29 | direction = values[i + 1] - values[i] 30 | break 31 | i += 1 32 | 33 | # All values are the same! 34 | if i == n - 1: 35 | return 1 36 | 37 | # Calculate the length of the wiggle sequence. 38 | last = values[0] 39 | length = 2 40 | while i < n: 41 | if (values[i] - last) * direction < 0: 42 | direction *= -1 43 | length += 1 44 | last = values[i] 45 | i += 1 46 | return length 47 | 48 | 49 | def main(): 50 | print('Please run this solution on LeetCode.') 51 | print('https://leetcode.com/problems/non-overlapping-intervals/') 52 | 53 | if __name__ == '__main__': 54 | main() 55 | -------------------------------------------------------------------------------- /leetcode/algorithms/wildcard-matching/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/wildcard-matching/](https://leetcode.com/problems/wildcard-matching/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/wildcard-matching/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 4 | class Solution(object): 5 | def isMatch(self, s, p): 6 | """ 7 | Returns a boolean indicating if the pattern p matches string s. See 8 | LeetCode problem description for full pattern spec. 9 | """ 10 | n = len(s) 11 | m = len(p) 12 | 13 | # If the pattern has more non-star chars than s has total chars, there 14 | # is no way we can match the pattern even if we ignore all stars.' 15 | if (m - p.count('*') > n): 16 | return False 17 | 18 | # Each lastDP[i] represents isMatch(s[:i], p[:j]) for previous j. We do 19 | # not need a full 2D matrix since the recursive relation only depends 20 | # on a sub-problem that is one level lower. 21 | lastDP = [False] * (n + 1) 22 | lastDP[0] = True 23 | 24 | for j in range(1, m + 1): 25 | # Create DP for the current j. 26 | nextDP = [False] * (n + 1) 27 | 28 | # Empty s matches p prefix if prefix contains only *'s. 29 | nextDP[0] = lastDP[0] and p[j - 1] == '*' 30 | 31 | for i in range(1, n + 1): 32 | if p[j - 1] == '*': 33 | # Skip * or current character. 34 | nextDP[i] = lastDP[i] or nextDP[i - 1] 35 | elif p[j - 1] == '?': 36 | # Skip current character and ?. 37 | nextDP[i] = lastDP[i - 1] 38 | else: 39 | # Ensure characters match and that s[:i] matches p[:j]. 40 | nextDP[i] = (s[i - 1] == p[j - 1]) and \ 41 | lastDP[i - 1] 42 | lastDP = nextDP 43 | return lastDP[-1] 44 | 45 | 46 | def main(): 47 | print('Please run this solution on LeetCode.') 48 | print('https://leetcode.com/problems/wildcard-matching/') 49 | 50 | if __name__ == '__main__': 51 | main() 52 | -------------------------------------------------------------------------------- /leetcode/algorithms/word-break/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | [https://leetcode.com/problems/word-break/](https://leetcode.com/problems/word-break/) 4 | 5 | -------------------------------------------------------------------------------- /leetcode/algorithms/word-break/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | 4 | class Solution(object): 5 | def wordBreak(self, word, dictionary): 6 | """ 7 | Checks if the word can be broken up into words from the specified 8 | dictionary. 9 | 10 | :type word: str 11 | :type dictionary: List[str] 12 | :rtype: bool 13 | """ 14 | n = len(word) 15 | if n == 0 or len(dictionary) == 0: 16 | return False 17 | 18 | # Turn the dictionary into a set for ~O(1) lookup. 19 | dictionary = set(dictionary) 20 | 21 | # Each dp[i] indicates if we can word break word[:i] 22 | dp = [False] * (n + 1) 23 | dp[0] = True 24 | 25 | # word[:i] can be broken up if (1) there exists a j such that word[:j] 26 | # can be broken up and suffix word[j:i] is in the dictionary or (2) 27 | # word[:i] is in the dictionary. 28 | for i in range(1, n + 1): 29 | # Find a prefix word[:j] that can be broken up. This includes the 30 | # empty string to handle case 2. 31 | for j in range(0, i): 32 | if not dp[j]: 33 | continue 34 | suffix = word[j:i] 35 | if suffix in dictionary: 36 | dp[i] = True 37 | break 38 | 39 | return dp[-1] 40 | 41 | 42 | def main(): 43 | print('Please run this solution on LeetCode.') 44 | print('https://leetcode.com/problems/word-break/') 45 | 46 | if __name__ == '__main__': 47 | main() 48 | -------------------------------------------------------------------------------- /lib/cpp/kmp/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++14 -Wall -o out 3 | 4 | default: out run 5 | 6 | out: main.cpp 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /lib/cpp/kmp/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | Generic implementation of [Knuth-Morris-Pratt](https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm) algorithm. 4 | 5 | -------------------------------------------------------------------------------- /lib/cpp/kmp/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | // 7 | // Copy wrapper around std::advance 8 | // 9 | template 10 | Iterator offset(Iterator it, Distance dist) { 11 | std::advance(it, dist); 12 | return it; 13 | } 14 | 15 | // 16 | // Generic KMP iterator based algorithm. Returns a table F where each F[i] 17 | // represents the longest proper suffix of S[0...i] that is also a prefix of 18 | // S[0...i] where S = [begin, end). 19 | // 20 | template 21 | std::vector kmp(Iterator begin, Iterator end) { 22 | // Setup table and base case. 23 | std::vector F(std::distance(begin, end)); 24 | F[0] = 0; 25 | 26 | // Setup iterator and track the index/distance we are from start of 27 | // sequence. 28 | Iterator it = next(begin); 29 | int i = 1; 30 | 31 | while (it != end) { 32 | int j = F[i - 1]; 33 | Iterator jIt = offset(begin, j); 34 | 35 | while (j > 0 && *jIt != *it) { 36 | j = F[j - 1]; 37 | jIt = offset(begin, j); 38 | } 39 | 40 | if (*jIt == *it) { 41 | j++; 42 | } 43 | 44 | F[i] = j; 45 | 46 | it++; 47 | i++; 48 | } 49 | 50 | return F; 51 | } 52 | 53 | // 54 | // Returns indexes in T where full occurences of P begin. 55 | // 56 | std::vector find(const std::string& P, 57 | const std::string& T, 58 | char separator = '#') { 59 | std::string S = P + std::string(1, separator) + T; 60 | std::vector F = kmp(S.begin(), S.end()); 61 | std::vector index; 62 | 63 | for (size_t i = 0; i < F.size(); i++) { 64 | if (F[i] == static_cast(P.size())) { 65 | index.push_back(i - 2 * P.size()); 66 | } 67 | } 68 | 69 | return index; 70 | } 71 | 72 | int main() { 73 | assert(find("a", "a") == std::vector({0})); 74 | assert(find("sda", "sadasda") == std::vector({4})); 75 | assert(find("rishi", "rishrisrishirishirishrishiririshi") == 76 | std::vector({7, 12, 21, 28})); 77 | assert(find("aa", "aaaa") == std::vector({0, 1, 2})); 78 | assert(find("AABA", "AABAACAADAABAABA") == std::vector({0, 9, 12})); 79 | assert(find("TEST", "THIS IS A TEST TEXT") == std::vector({10})); 80 | 81 | std::cout << "Tests pass!" << std::endl; 82 | 83 | return 0; 84 | } 85 | 86 | -------------------------------------------------------------------------------- /lib/cpp/manachers/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++14 -Wall -o out 3 | 4 | default: out run 5 | 6 | out: main.cpp 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /lib/cpp/manachers/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | Implementation of [Manacher's Algorithm](http://www.geeksforgeeks.org/manachers-algorithm-linear-time-longest-palindromic-substring-part-1/). 4 | This [article](http://articles.leetcode.com/longest-palindromic-substring-part-ii) nicely explains the logic behind it. 5 | 6 | -------------------------------------------------------------------------------- /lib/cpp/z-algorithm/Makefile: -------------------------------------------------------------------------------- 1 | CXX := g++ 2 | CXXFLAGS := -std=c++14 -Wall -o out 3 | 4 | default: out run 5 | 6 | out: main.cpp 7 | $(CXX) $(CXXFLAGS) main.cpp 8 | 9 | clean: 10 | $(RM) out 11 | 12 | run: 13 | ./out 14 | -------------------------------------------------------------------------------- /lib/cpp/z-algorithm/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | Generic implementation of [Z-Algorithm](http://www.geeksforgeeks.org/z-algorithm-linear-time-pattern-searching-algorithm/). 4 | This [article](https://ivanyu.me/blog/2013/10/15/z-algorithm/) offers an excellent explanation of the algorithm. 5 | 6 | -------------------------------------------------------------------------------- /lib/python/kmp/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | Generic implementation of [Knuth-Morris-Pratt](https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm) algorithm. 4 | 5 | -------------------------------------------------------------------------------- /lib/python/kmp/kmp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | 4 | def kmp(S): 5 | """Runs the Knuth-Morris-Pratt algorithm on S. 6 | 7 | Returns a table F such that F[i] is the longest proper suffix of S[0...i] 8 | that is also a prefix of S[0...i]. 9 | """ 10 | n = len(S) 11 | 12 | if n == 0: 13 | return [] 14 | 15 | F = [0] * n 16 | 17 | for i in range(1, n): 18 | k = F[i - 1] 19 | 20 | while k > 0 and S[k] != S[i]: 21 | k = F[k - 1] 22 | 23 | if S[k] == S[i]: 24 | k += 1 25 | 26 | F[i] = k 27 | 28 | return F 29 | 30 | 31 | def find(T, P, separator='#'): 32 | """Returns a list of indexes in T where full occurences of P begin.""" 33 | S = P + separator + T 34 | F = kmp(S) 35 | return [i - 2 * len(P) for i in range(len(F)) if F[i] == len(P)] 36 | 37 | 38 | def main(): 39 | print('Begin tests...') 40 | 41 | assert find('a', 'a') == [0] 42 | assert find('sadasda', 'sda') == [4] 43 | assert find('rishrisrishirishirishrishiririshi', 'rishi') == \ 44 | [7, 12, 21, 28] 45 | assert find('aaaa', 'aa') == [0, 1, 2] 46 | assert find('AABAACAADAABAABA', 'AABA') == [0, 9, 12] 47 | assert find('THIS IS A TEST TEXT', 'TEST') == [10] 48 | 49 | print('Tests pass!') 50 | 51 | if __name__ == '__main__': 52 | main() 53 | -------------------------------------------------------------------------------- /lib/python/manachers/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | Implementation of [Manacher's Algorithm](http://www.geeksforgeeks.org/manachers-algorithm-linear-time-longest-palindromic-substring-part-1/). 4 | This [article](http://articles.leetcode.com/longest-palindromic-substring-part-ii) nicely explains the logic behind it. 5 | 6 | -------------------------------------------------------------------------------- /linter.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | BASEDIR=$(dirname "$0") 4 | 5 | cpplint $(find ${BASEDIR} -name \*.h -or -name \*.cpp) 6 | pep8 $(find ${BASEDIR} -name \*.py) 7 | --------------------------------------------------------------------------------