From 6495e14da0a6bb7b48bfcd90eaf4b290807f971d Mon Sep 17 00:00:00 2001 From: Ciro Santilli Date: Thu, 10 Dec 2015 07:29:24 -0200 Subject: [PATCH 01/29] gitignore java *.class files for those without IDE --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 1f1c65c40..25a4d2a65 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .idea algorithms-java/out +*.class From cc7fc84f38679f8808f92a3ac77f2e0117fffb24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ciro=20Santilli=20=E5=85=AD=E5=9B=9B=E4=BA=8B=E4=BB=B6=20?= =?UTF-8?q?=E6=B3=95=E8=BD=AE=E5=8A=9F?= Date: Thu, 10 Dec 2015 07:29:24 -0200 Subject: [PATCH 02/29] gitignore java *.class files for those without IDE --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 1f1c65c40..25a4d2a65 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .idea algorithms-java/out +*.class From 728ad252ab04b5ee0d6817d7ef6c9c724f9f71b5 Mon Sep 17 00:00:00 2001 From: Ciro Santilli Date: Thu, 10 Dec 2015 07:21:27 -0200 Subject: [PATCH 03/29] java LRUCache with LinkedHashMap --- algorithms/java/src/lruCache/LRUCache.java | 45 +++++++++++++++++ .../java/src/lruCache/LRUCacheTest.java | 49 +++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 algorithms/java/src/lruCache/LRUCache.java create mode 100644 algorithms/java/src/lruCache/LRUCacheTest.java diff --git a/algorithms/java/src/lruCache/LRUCache.java b/algorithms/java/src/lruCache/LRUCache.java new file mode 100644 index 000000000..5ea5c2950 --- /dev/null +++ b/algorithms/java/src/lruCache/LRUCache.java @@ -0,0 +1,45 @@ +/* +Analogous to the C++ solution at: +https://github.com/haoel/leetcode/blob/625ad10464701fc4177b9ef33c8ad052d0a7d984/algorithms/cpp/LRUCache/LRUCache.cpp +which uses linked list + hash map. But the Java stdlib provides LinkedHashMap +which already implements that for us, making this solution shorter. + +This could also be done by using, but that generates +some inheritance boilerplate, and ends up taking the same number of lines: +https://github.com/cirosantilli/haoel-leetcode/commit/ff04930b2dc31f270854e40b560723577c7b49fd +*/ + +import java.util.LinkedHashMap; +import java.util.Iterator; + +public class LRUCache { + + private int capacity; + private LinkedHashMap map; + + public LRUCache(int capacity) { + this.capacity = capacity; + this.map = new LinkedHashMap<>(); + } + + public int get(int key) { + Integer value = this.map.get(key); + if (value == null) { + value = -1; + } else { + this.set(key, value); + } + return value; + } + + public void set(int key, int value) { + if (this.map.containsKey(key)) { + this.map.remove(key); + } else if (this.map.size() == this.capacity) { + Iterator it = this.map.keySet().iterator(); + it.next(); + it.remove(); + } + map.put(key, value); + } +} diff --git a/algorithms/java/src/lruCache/LRUCacheTest.java b/algorithms/java/src/lruCache/LRUCacheTest.java new file mode 100644 index 000000000..b8166873e --- /dev/null +++ b/algorithms/java/src/lruCache/LRUCacheTest.java @@ -0,0 +1,49 @@ +import java.util.ArrayList; + +import org.junit.Test; +import static org.junit.Assert.*; + +public class LRUCacheTest { + + private LRUCache c; + + public LRUCacheTest() { + this.c = new LRUCache(2); + } + + @Test + public void testCacheStartsEmpty() { + assertEquals(c.get(1), -1); + } + + @Test + public void testSetBelowCapacity() { + c.set(1, 1); + assertEquals(c.get(1), 1); + assertEquals(c.get(2), -1); + c.set(2, 4); + assertEquals(c.get(1), 1); + assertEquals(c.get(2), 4); + } + + @Test + public void testCapacityReachedOldestRemoved() { + c.set(1, 1); + c.set(2, 4); + c.set(3, 9); + assertEquals(c.get(1), -1); + assertEquals(c.get(2), 4); + assertEquals(c.get(3), 9); + } + + @Test + public void testGetRenewsEntry() { + c.set(1, 1); + c.set(2, 4); + assertEquals(c.get(1), 1); + c.set(3, 9); + assertEquals(c.get(1), 1); + assertEquals(c.get(2), -1); + assertEquals(c.get(3), 9); + } +} From 2a8222328fa9d677f26059a09602a10c7b1a029d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ciro=20Santilli=20=E5=85=AD=E5=9B=9B=E4=BA=8B=E4=BB=B6=20?= =?UTF-8?q?=E6=B3=95=E8=BD=AE=E5=8A=9F?= Date: Thu, 10 Dec 2015 07:21:27 -0200 Subject: [PATCH 04/29] java LRUCache with LinkedHashMap --- algorithms/java/src/lruCache/LRUCache.java | 45 +++++++++++++++++ .../java/src/lruCache/LRUCacheTest.java | 49 +++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 algorithms/java/src/lruCache/LRUCache.java create mode 100644 algorithms/java/src/lruCache/LRUCacheTest.java diff --git a/algorithms/java/src/lruCache/LRUCache.java b/algorithms/java/src/lruCache/LRUCache.java new file mode 100644 index 000000000..5ea5c2950 --- /dev/null +++ b/algorithms/java/src/lruCache/LRUCache.java @@ -0,0 +1,45 @@ +/* +Analogous to the C++ solution at: +https://github.com/haoel/leetcode/blob/625ad10464701fc4177b9ef33c8ad052d0a7d984/algorithms/cpp/LRUCache/LRUCache.cpp +which uses linked list + hash map. But the Java stdlib provides LinkedHashMap +which already implements that for us, making this solution shorter. + +This could also be done by using, but that generates +some inheritance boilerplate, and ends up taking the same number of lines: +https://github.com/cirosantilli/haoel-leetcode/commit/ff04930b2dc31f270854e40b560723577c7b49fd +*/ + +import java.util.LinkedHashMap; +import java.util.Iterator; + +public class LRUCache { + + private int capacity; + private LinkedHashMap map; + + public LRUCache(int capacity) { + this.capacity = capacity; + this.map = new LinkedHashMap<>(); + } + + public int get(int key) { + Integer value = this.map.get(key); + if (value == null) { + value = -1; + } else { + this.set(key, value); + } + return value; + } + + public void set(int key, int value) { + if (this.map.containsKey(key)) { + this.map.remove(key); + } else if (this.map.size() == this.capacity) { + Iterator it = this.map.keySet().iterator(); + it.next(); + it.remove(); + } + map.put(key, value); + } +} diff --git a/algorithms/java/src/lruCache/LRUCacheTest.java b/algorithms/java/src/lruCache/LRUCacheTest.java new file mode 100644 index 000000000..b8166873e --- /dev/null +++ b/algorithms/java/src/lruCache/LRUCacheTest.java @@ -0,0 +1,49 @@ +import java.util.ArrayList; + +import org.junit.Test; +import static org.junit.Assert.*; + +public class LRUCacheTest { + + private LRUCache c; + + public LRUCacheTest() { + this.c = new LRUCache(2); + } + + @Test + public void testCacheStartsEmpty() { + assertEquals(c.get(1), -1); + } + + @Test + public void testSetBelowCapacity() { + c.set(1, 1); + assertEquals(c.get(1), 1); + assertEquals(c.get(2), -1); + c.set(2, 4); + assertEquals(c.get(1), 1); + assertEquals(c.get(2), 4); + } + + @Test + public void testCapacityReachedOldestRemoved() { + c.set(1, 1); + c.set(2, 4); + c.set(3, 9); + assertEquals(c.get(1), -1); + assertEquals(c.get(2), 4); + assertEquals(c.get(3), 9); + } + + @Test + public void testGetRenewsEntry() { + c.set(1, 1); + c.set(2, 4); + assertEquals(c.get(1), 1); + c.set(3, 9); + assertEquals(c.get(1), 1); + assertEquals(c.get(2), -1); + assertEquals(c.get(3), 9); + } +} From 738bc45ec9969f4bc7ca0a11394b7cd06243090d Mon Sep 17 00:00:00 2001 From: Vally Date: Mon, 28 Dec 2015 18:36:22 +0200 Subject: [PATCH 05/29] added bulbSwitcher --- README.md | 1 + algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp | 44 ++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp diff --git a/README.md b/README.md index 3f71fe9be..fc0f24320 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ LeetCode | # | Title | Solution | Difficulty | |---| ----- | -------- | ---------- | +|319|[Bulb Switcher](https://leetcode.com/problems/bulb-switcher/) | [C++](./algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp)|Medium| |315|[Count of Smaller Numbers After Self](https://leetcode.com/problems/count-of-smaller-numbers-after-self/) | [C++](./algorithms/cpp/countOfSmallerNumbersAfterSelf/countOfSmallerNumbersAfterSelf.cpp)|Hard| |307|[Range Sum Query - Mutable](https://leetcode.com/problems/range-sum-query-mutable/) | [C++](./algorithms/cpp/rangeSumQuery-Immutable/rangeSumQuery-Mutable/RangeSumQueryMutable.cpp)|Medium| |306|[Additive Number](https://leetcode.com/problems/additive-number/) | [C++](./algorithms/cpp/additiveNumber/AdditiveNumber.cpp)|Medium| diff --git a/algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp b/algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp new file mode 100644 index 000000000..04b046391 --- /dev/null +++ b/algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp @@ -0,0 +1,44 @@ +// Source : https://leetcode.com/problems/bulb-switcher/ +// Author : Calinescu Valentin +// Date : 2015-12-28 + +/*************************************************************************************** + * + * There are n bulbs that are initially off. You first turn on all the bulbs. Then, you + * turn off every second bulb. On the third round, you toggle every third bulb (turning + * on if it's off or turning off if it's on). For the nth round, you only toggle the + * last bulb. Find how many bulbs are on after n rounds. + * + * Example: + * + * Given n = 3. + * + * At first, the three bulbs are [off, off, off]. + * After first round, the three bulbs are [on, on, on]. + * After second round, the three bulbs are [on, off, on]. + * After third round, the three bulbs are [on, off, off]. + * + * So you should return 1, because there is only one bulb is on. + * + ***************************************************************************************/ + /* + * Solution 1 - O(1) + * ========= + * + * We notice that for every light bulb on position i there will be one toggle for every + * one of its divisors, given that you toggle all of the multiples of one number. The + * total number of toggles is irrelevant, because there are only 2 possible positions(on, + * off). We quickly find that 2 toggles cancel each other so given that the start position + * is always off a light bulb will be in if it has been toggled an odd number of times. + * The only integers with an odd number of divisors are perfect squares(because the square + * root only appears once, not like the other divisors that form pairs). The problem comes + * down to finding the number of perfect squares <= n. That number is the integer part of + * the square root of n. + * + */ +class Solution { +public: + int bulbSwitch(int n) { + return (int)sqrt(n); + } +}; From a6368c99b3a1edc99489a152a54d849d10a913fc Mon Sep 17 00:00:00 2001 From: Vally Date: Mon, 28 Dec 2015 18:36:22 +0200 Subject: [PATCH 06/29] added bulbSwitcher --- README.md | 1 + algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp | 44 ++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp diff --git a/README.md b/README.md index 3f71fe9be..fc0f24320 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ LeetCode | # | Title | Solution | Difficulty | |---| ----- | -------- | ---------- | +|319|[Bulb Switcher](https://leetcode.com/problems/bulb-switcher/) | [C++](./algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp)|Medium| |315|[Count of Smaller Numbers After Self](https://leetcode.com/problems/count-of-smaller-numbers-after-self/) | [C++](./algorithms/cpp/countOfSmallerNumbersAfterSelf/countOfSmallerNumbersAfterSelf.cpp)|Hard| |307|[Range Sum Query - Mutable](https://leetcode.com/problems/range-sum-query-mutable/) | [C++](./algorithms/cpp/rangeSumQuery-Immutable/rangeSumQuery-Mutable/RangeSumQueryMutable.cpp)|Medium| |306|[Additive Number](https://leetcode.com/problems/additive-number/) | [C++](./algorithms/cpp/additiveNumber/AdditiveNumber.cpp)|Medium| diff --git a/algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp b/algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp new file mode 100644 index 000000000..04b046391 --- /dev/null +++ b/algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp @@ -0,0 +1,44 @@ +// Source : https://leetcode.com/problems/bulb-switcher/ +// Author : Calinescu Valentin +// Date : 2015-12-28 + +/*************************************************************************************** + * + * There are n bulbs that are initially off. You first turn on all the bulbs. Then, you + * turn off every second bulb. On the third round, you toggle every third bulb (turning + * on if it's off or turning off if it's on). For the nth round, you only toggle the + * last bulb. Find how many bulbs are on after n rounds. + * + * Example: + * + * Given n = 3. + * + * At first, the three bulbs are [off, off, off]. + * After first round, the three bulbs are [on, on, on]. + * After second round, the three bulbs are [on, off, on]. + * After third round, the three bulbs are [on, off, off]. + * + * So you should return 1, because there is only one bulb is on. + * + ***************************************************************************************/ + /* + * Solution 1 - O(1) + * ========= + * + * We notice that for every light bulb on position i there will be one toggle for every + * one of its divisors, given that you toggle all of the multiples of one number. The + * total number of toggles is irrelevant, because there are only 2 possible positions(on, + * off). We quickly find that 2 toggles cancel each other so given that the start position + * is always off a light bulb will be in if it has been toggled an odd number of times. + * The only integers with an odd number of divisors are perfect squares(because the square + * root only appears once, not like the other divisors that form pairs). The problem comes + * down to finding the number of perfect squares <= n. That number is the integer part of + * the square root of n. + * + */ +class Solution { +public: + int bulbSwitch(int n) { + return (int)sqrt(n); + } +}; From cc1f6554dedcdb0b8aab5b339d5ad2604733e70a Mon Sep 17 00:00:00 2001 From: Vally Date: Mon, 28 Dec 2015 19:44:50 +0200 Subject: [PATCH 07/29] added coinChange --- README.md | 1 + algorithms/cpp/coinChange/coinChange.cpp | 62 ++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 algorithms/cpp/coinChange/coinChange.cpp diff --git a/README.md b/README.md index fc0f24320..539f6b37d 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ LeetCode | # | Title | Solution | Difficulty | |---| ----- | -------- | ---------- | +|322|[Coin Change](https://leetcode.com/problems/coin-change/) | [C++](./algorithms/cpp/coinChange/coinChange.cpp)|Medium| |319|[Bulb Switcher](https://leetcode.com/problems/bulb-switcher/) | [C++](./algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp)|Medium| |315|[Count of Smaller Numbers After Self](https://leetcode.com/problems/count-of-smaller-numbers-after-self/) | [C++](./algorithms/cpp/countOfSmallerNumbersAfterSelf/countOfSmallerNumbersAfterSelf.cpp)|Hard| |307|[Range Sum Query - Mutable](https://leetcode.com/problems/range-sum-query-mutable/) | [C++](./algorithms/cpp/rangeSumQuery-Immutable/rangeSumQuery-Mutable/RangeSumQueryMutable.cpp)|Medium| diff --git a/algorithms/cpp/coinChange/coinChange.cpp b/algorithms/cpp/coinChange/coinChange.cpp new file mode 100644 index 000000000..e8ddc9c51 --- /dev/null +++ b/algorithms/cpp/coinChange/coinChange.cpp @@ -0,0 +1,62 @@ +// Source : https://leetcode.com/problems/coin-change/ +// Author : Calinescu Valentin +// Date : 2015-12-28 + +/*************************************************************************************** + * + * You are given coins of different denominations and a total amount of money amount. + * Write a function to compute the fewest number of coins that you need to make up that + * amount. If that amount of money cannot be made up by any combination of the coins, + * return -1. + * + * Example 1: + * coins = [1, 2, 5], amount = 11 + * return 3 (11 = 5 + 5 + 1) + * + * Example 2: + * coins = [2], amount = 3 + * return -1. + * + * Note: + * You may assume that you have an infinite number of each kind of coin. + * + * Credits: + * Special thanks to @jianchao.li.fighter for adding this problem and creating all test + * cases. + * + ***************************************************************************************/ + /* + * Solution 1 - O(N * amount) + * ========= + * + * This problem can be solved using dynamic programming, thus building the optimal + * solution from previous smaller ones. For every coin of value t and every sum of money + * i the sum can be traced back to a previous sum i - t that was already computed and uses + * the smallest number of coins possible. This way we can construct every sum i as the + * minimum of all these previous sums for every coin value. To be sure we'll find a minimum + * we can populate the solution vector with an amount bigger than the maximum possible, + * which is amount + 1(when the sum is made up of only coins of value 1). The only exception + * is sol[0] which is 0 as we need 0 coins to have a sum of 0. In the end we need to look + * if the program found a solution in sol[amount] or it remained the same, in which case we + * can return -1. + * + */ +class Solution { +public: + + int coinChange(vector& coins, int amount) { + int sol[amount + 1]; + sol[0] = 0; + for(int i = 1; i <= amount; i++) + sol[i] = amount + 1; + for(int i = 0; i < coins.size(); i++) + { + for(int j = coins[i]; j <= amount; j++) + sol[j] = min(sol[j], sol[j - coins[i]] + 1); + } + if(sol[amount] != amount + 1) + return sol[amount]; + else + return -1; + } +}; From 7c7528fbc4b1805c47428fe7cce6fb9bfc9a7565 Mon Sep 17 00:00:00 2001 From: Vally Date: Mon, 28 Dec 2015 19:44:50 +0200 Subject: [PATCH 08/29] added coinChange --- README.md | 1 + algorithms/cpp/coinChange/coinChange.cpp | 62 ++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 algorithms/cpp/coinChange/coinChange.cpp diff --git a/README.md b/README.md index fc0f24320..539f6b37d 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ LeetCode | # | Title | Solution | Difficulty | |---| ----- | -------- | ---------- | +|322|[Coin Change](https://leetcode.com/problems/coin-change/) | [C++](./algorithms/cpp/coinChange/coinChange.cpp)|Medium| |319|[Bulb Switcher](https://leetcode.com/problems/bulb-switcher/) | [C++](./algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp)|Medium| |315|[Count of Smaller Numbers After Self](https://leetcode.com/problems/count-of-smaller-numbers-after-self/) | [C++](./algorithms/cpp/countOfSmallerNumbersAfterSelf/countOfSmallerNumbersAfterSelf.cpp)|Hard| |307|[Range Sum Query - Mutable](https://leetcode.com/problems/range-sum-query-mutable/) | [C++](./algorithms/cpp/rangeSumQuery-Immutable/rangeSumQuery-Mutable/RangeSumQueryMutable.cpp)|Medium| diff --git a/algorithms/cpp/coinChange/coinChange.cpp b/algorithms/cpp/coinChange/coinChange.cpp new file mode 100644 index 000000000..e8ddc9c51 --- /dev/null +++ b/algorithms/cpp/coinChange/coinChange.cpp @@ -0,0 +1,62 @@ +// Source : https://leetcode.com/problems/coin-change/ +// Author : Calinescu Valentin +// Date : 2015-12-28 + +/*************************************************************************************** + * + * You are given coins of different denominations and a total amount of money amount. + * Write a function to compute the fewest number of coins that you need to make up that + * amount. If that amount of money cannot be made up by any combination of the coins, + * return -1. + * + * Example 1: + * coins = [1, 2, 5], amount = 11 + * return 3 (11 = 5 + 5 + 1) + * + * Example 2: + * coins = [2], amount = 3 + * return -1. + * + * Note: + * You may assume that you have an infinite number of each kind of coin. + * + * Credits: + * Special thanks to @jianchao.li.fighter for adding this problem and creating all test + * cases. + * + ***************************************************************************************/ + /* + * Solution 1 - O(N * amount) + * ========= + * + * This problem can be solved using dynamic programming, thus building the optimal + * solution from previous smaller ones. For every coin of value t and every sum of money + * i the sum can be traced back to a previous sum i - t that was already computed and uses + * the smallest number of coins possible. This way we can construct every sum i as the + * minimum of all these previous sums for every coin value. To be sure we'll find a minimum + * we can populate the solution vector with an amount bigger than the maximum possible, + * which is amount + 1(when the sum is made up of only coins of value 1). The only exception + * is sol[0] which is 0 as we need 0 coins to have a sum of 0. In the end we need to look + * if the program found a solution in sol[amount] or it remained the same, in which case we + * can return -1. + * + */ +class Solution { +public: + + int coinChange(vector& coins, int amount) { + int sol[amount + 1]; + sol[0] = 0; + for(int i = 1; i <= amount; i++) + sol[i] = amount + 1; + for(int i = 0; i < coins.size(); i++) + { + for(int j = coins[i]; j <= amount; j++) + sol[j] = min(sol[j], sol[j - coins[i]] + 1); + } + if(sol[amount] != amount + 1) + return sol[amount]; + else + return -1; + } +}; From 38f5b0b655c65eca4a6d1fb6bd65776e0112ad06 Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Thu, 14 Jan 2016 09:31:58 +0800 Subject: [PATCH 09/29] typo --- .../findMinimumInRotatedSortedArray.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/algorithms/cpp/findMinimumInRotatedSortedArray/findMinimumInRotatedSortedArray.cpp b/algorithms/cpp/findMinimumInRotatedSortedArray/findMinimumInRotatedSortedArray.cpp index 2ac3e33a3..9c8cc43cb 100644 --- a/algorithms/cpp/findMinimumInRotatedSortedArray/findMinimumInRotatedSortedArray.cpp +++ b/algorithms/cpp/findMinimumInRotatedSortedArray/findMinimumInRotatedSortedArray.cpp @@ -38,7 +38,7 @@ int findMin(vector &num) { } // The array is rotated - // Spli it into two part, the minimal value must be the rotated part + // Split it into two part, the minimal value must be the rotated part // if the left part is rotated, warch the left part if (num[low] > num [mid]){ From e8d5796753a79cabf44fbd635033be0918c0aafd Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Thu, 14 Jan 2016 09:31:58 +0800 Subject: [PATCH 10/29] typo --- .../findMinimumInRotatedSortedArray.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/algorithms/cpp/findMinimumInRotatedSortedArray/findMinimumInRotatedSortedArray.cpp b/algorithms/cpp/findMinimumInRotatedSortedArray/findMinimumInRotatedSortedArray.cpp index 2ac3e33a3..9c8cc43cb 100644 --- a/algorithms/cpp/findMinimumInRotatedSortedArray/findMinimumInRotatedSortedArray.cpp +++ b/algorithms/cpp/findMinimumInRotatedSortedArray/findMinimumInRotatedSortedArray.cpp @@ -38,7 +38,7 @@ int findMin(vector &num) { } // The array is rotated - // Spli it into two part, the minimal value must be the rotated part + // Split it into two part, the minimal value must be the rotated part // if the left part is rotated, warch the left part if (num[low] > num [mid]){ From be27a989a5e0f330f0936b68835c31921edc9c54 Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Thu, 14 Jan 2016 09:32:20 +0800 Subject: [PATCH 11/29] New Problem "Power of Three" --- README.md | 1 + algorithms/cpp/powerOfThree/PowerOfThree.cpp | 66 ++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 algorithms/cpp/powerOfThree/PowerOfThree.cpp diff --git a/README.md b/README.md index 539f6b37d..67b0f1199 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ LeetCode | # | Title | Solution | Difficulty | |---| ----- | -------- | ---------- | +|326|[Power of Three](https://leetcode.com/problems/power-of-three/) | [C++](./algorithms/cpp/powerOfThree/PowerOfThree.cpp)|Easy| |322|[Coin Change](https://leetcode.com/problems/coin-change/) | [C++](./algorithms/cpp/coinChange/coinChange.cpp)|Medium| |319|[Bulb Switcher](https://leetcode.com/problems/bulb-switcher/) | [C++](./algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp)|Medium| |315|[Count of Smaller Numbers After Self](https://leetcode.com/problems/count-of-smaller-numbers-after-self/) | [C++](./algorithms/cpp/countOfSmallerNumbersAfterSelf/countOfSmallerNumbersAfterSelf.cpp)|Hard| diff --git a/algorithms/cpp/powerOfThree/PowerOfThree.cpp b/algorithms/cpp/powerOfThree/PowerOfThree.cpp new file mode 100644 index 000000000..a75143b91 --- /dev/null +++ b/algorithms/cpp/powerOfThree/PowerOfThree.cpp @@ -0,0 +1,66 @@ +// Source : https://leetcode.com/problems/power-of-three/ +// Author : Hao Chen +// Date : 2016-01-14 + +/*************************************************************************************** + * + * Given an integer, write a function to determine if it is a power of three. + * + * Follow up: + * Could you do it without using any loop / recursion? + * + * Credits:Special thanks to @dietpepsi for adding this problem and creating all test + * cases. + * + ***************************************************************************************/ + +class Solution { + +public: + + bool isPowerOfThree(int n) { + return isPowerOfThree03(n); //140ms + return isPowerOfThree02(n);//130ms + return isPowerOfThree01(n); //140ms + return isPowerOfThree_loop(n); //136ms + return isPowerOfThree_recursive(n); //168ms + } + + bool isPowerOfThree03(int n) { + double logRes = log10(n)/log10(3); + return (logRes - int(logRes) == 0); + } + bool isPowerOfThree02(int n) { + return n>0 ? (1162261467%n==0) : false; + } + + void init(unordered_map& power ){ + int p = 1; + power[1]=true; + while(1){ + p *= 3; + power[p] = true; + if (p > INT_MAX/3) break; + + } + } + bool isPowerOfThree01(int n) { + static unordered_map power; + if (power.size()==0) init(power); + return power.find(n) != power.end(); + } + + bool isPowerOfThree_loop(int n) { + for(;n>0;n /= 3){ + if (n==1 || n==3) return true; + if (n%3 != 0) return false; + } + return false; + } + + bool isPowerOfThree_recursive(int n) { + if ( n == 1 || n == 3) return true; + if ( n==0 || n%3 != 0 ) return false; + return isPowerOfThree_recursive(n/3); + } +}; From 73279a1a75af7011a864e6c2d496fe3df0162e98 Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Thu, 14 Jan 2016 09:32:20 +0800 Subject: [PATCH 12/29] New Problem "Power of Three" --- README.md | 1 + algorithms/cpp/powerOfThree/PowerOfThree.cpp | 66 ++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 algorithms/cpp/powerOfThree/PowerOfThree.cpp diff --git a/README.md b/README.md index 539f6b37d..67b0f1199 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ LeetCode | # | Title | Solution | Difficulty | |---| ----- | -------- | ---------- | +|326|[Power of Three](https://leetcode.com/problems/power-of-three/) | [C++](./algorithms/cpp/powerOfThree/PowerOfThree.cpp)|Easy| |322|[Coin Change](https://leetcode.com/problems/coin-change/) | [C++](./algorithms/cpp/coinChange/coinChange.cpp)|Medium| |319|[Bulb Switcher](https://leetcode.com/problems/bulb-switcher/) | [C++](./algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp)|Medium| |315|[Count of Smaller Numbers After Self](https://leetcode.com/problems/count-of-smaller-numbers-after-self/) | [C++](./algorithms/cpp/countOfSmallerNumbersAfterSelf/countOfSmallerNumbersAfterSelf.cpp)|Hard| diff --git a/algorithms/cpp/powerOfThree/PowerOfThree.cpp b/algorithms/cpp/powerOfThree/PowerOfThree.cpp new file mode 100644 index 000000000..a75143b91 --- /dev/null +++ b/algorithms/cpp/powerOfThree/PowerOfThree.cpp @@ -0,0 +1,66 @@ +// Source : https://leetcode.com/problems/power-of-three/ +// Author : Hao Chen +// Date : 2016-01-14 + +/*************************************************************************************** + * + * Given an integer, write a function to determine if it is a power of three. + * + * Follow up: + * Could you do it without using any loop / recursion? + * + * Credits:Special thanks to @dietpepsi for adding this problem and creating all test + * cases. + * + ***************************************************************************************/ + +class Solution { + +public: + + bool isPowerOfThree(int n) { + return isPowerOfThree03(n); //140ms + return isPowerOfThree02(n);//130ms + return isPowerOfThree01(n); //140ms + return isPowerOfThree_loop(n); //136ms + return isPowerOfThree_recursive(n); //168ms + } + + bool isPowerOfThree03(int n) { + double logRes = log10(n)/log10(3); + return (logRes - int(logRes) == 0); + } + bool isPowerOfThree02(int n) { + return n>0 ? (1162261467%n==0) : false; + } + + void init(unordered_map& power ){ + int p = 1; + power[1]=true; + while(1){ + p *= 3; + power[p] = true; + if (p > INT_MAX/3) break; + + } + } + bool isPowerOfThree01(int n) { + static unordered_map power; + if (power.size()==0) init(power); + return power.find(n) != power.end(); + } + + bool isPowerOfThree_loop(int n) { + for(;n>0;n /= 3){ + if (n==1 || n==3) return true; + if (n%3 != 0) return false; + } + return false; + } + + bool isPowerOfThree_recursive(int n) { + if ( n == 1 || n == 3) return true; + if ( n==0 || n%3 != 0 ) return false; + return isPowerOfThree_recursive(n/3); + } +}; From 7b084c822038e474e2a595cf46af31f860a19917 Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Fri, 15 Jan 2016 15:03:32 +0800 Subject: [PATCH 13/29] another solution --- .../countOfSmallerNumbersAfterSelf.cpp | 79 ++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/algorithms/cpp/countOfSmallerNumbersAfterSelf/countOfSmallerNumbersAfterSelf.cpp b/algorithms/cpp/countOfSmallerNumbersAfterSelf/countOfSmallerNumbersAfterSelf.cpp index cac1435c4..badec47d2 100644 --- a/algorithms/cpp/countOfSmallerNumbersAfterSelf/countOfSmallerNumbersAfterSelf.cpp +++ b/algorithms/cpp/countOfSmallerNumbersAfterSelf/countOfSmallerNumbersAfterSelf.cpp @@ -1,5 +1,5 @@ // Source : https://leetcode.com/problems/count-of-smaller-numbers-after-self/ -// Author : Calinescu Valentin +// Author : Calinescu Valentin, Hao Chen // Date : 2015-12-08 /*************************************************************************************** @@ -73,3 +73,80 @@ class Solution { return sol; } }; + + +/*************************************************************************************** + * Another solution - Binary Search Tree + ***************************************************************************************/ + + +class BinarySearchTreeNode +{ + public: + int val; + int less; // count of members less than val + int count; // count of members equal val + BinarySearchTreeNode *left, *right; + BinarySearchTreeNode(int value) : val(value), less(0),count(1),left(NULL), right(NULL) {} +}; + +class BinarySearchTree +{ + private: + BinarySearchTreeNode* root; + public: + BinarySearchTree(const int value):root(new BinarySearchTreeNode(value)){ } + ~BinarySearchTree() { + freeTree(root); + } + void insert(const int value, int &numLessThan) { + insert(root, value, numLessThan); + } + private: + void freeTree(BinarySearchTreeNode* root){ + if (root == NULL) return; + if (root->left) freeTree(root->left); + if (root->right) freeTree(root->right); + delete root; + } + + void insert(BinarySearchTreeNode* root, const int value, int &numLessThan) { + + if(value < root->val) { // left + root->less++; + if(root->left == NULL) { + root->left = new BinarySearchTreeNode(value); + }else{ + this->insert(root->left, value, numLessThan); + } + } else if(value > root->val) { // right + numLessThan += root->less + root->count; + if(!root->right) { + root->right = new BinarySearchTreeNode(value); + }else{ + this->insert(root->right, value, numLessThan); + } + } else { + numLessThan += root->less; + root->count++; + return; + } + } +}; + +class Solution { + public: + vector countSmaller(vector& nums) { + vector counts(nums.size()); + if(nums.size() == 0) return counts; + + BinarySearchTree tree(nums[nums.size()-1]); + + for(int i = nums.size() - 2; i >= 0; i--) { + int numLessThan = 0; + tree.insert( nums[i], numLessThan); + counts[i] = numLessThan; + } + return counts; + } +}; From 12450188eceacab8e98e2ab1c02027e4ae380d9b Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Fri, 15 Jan 2016 15:03:32 +0800 Subject: [PATCH 14/29] another solution --- .../countOfSmallerNumbersAfterSelf.cpp | 79 ++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/algorithms/cpp/countOfSmallerNumbersAfterSelf/countOfSmallerNumbersAfterSelf.cpp b/algorithms/cpp/countOfSmallerNumbersAfterSelf/countOfSmallerNumbersAfterSelf.cpp index cac1435c4..badec47d2 100644 --- a/algorithms/cpp/countOfSmallerNumbersAfterSelf/countOfSmallerNumbersAfterSelf.cpp +++ b/algorithms/cpp/countOfSmallerNumbersAfterSelf/countOfSmallerNumbersAfterSelf.cpp @@ -1,5 +1,5 @@ // Source : https://leetcode.com/problems/count-of-smaller-numbers-after-self/ -// Author : Calinescu Valentin +// Author : Calinescu Valentin, Hao Chen // Date : 2015-12-08 /*************************************************************************************** @@ -73,3 +73,80 @@ class Solution { return sol; } }; + + +/*************************************************************************************** + * Another solution - Binary Search Tree + ***************************************************************************************/ + + +class BinarySearchTreeNode +{ + public: + int val; + int less; // count of members less than val + int count; // count of members equal val + BinarySearchTreeNode *left, *right; + BinarySearchTreeNode(int value) : val(value), less(0),count(1),left(NULL), right(NULL) {} +}; + +class BinarySearchTree +{ + private: + BinarySearchTreeNode* root; + public: + BinarySearchTree(const int value):root(new BinarySearchTreeNode(value)){ } + ~BinarySearchTree() { + freeTree(root); + } + void insert(const int value, int &numLessThan) { + insert(root, value, numLessThan); + } + private: + void freeTree(BinarySearchTreeNode* root){ + if (root == NULL) return; + if (root->left) freeTree(root->left); + if (root->right) freeTree(root->right); + delete root; + } + + void insert(BinarySearchTreeNode* root, const int value, int &numLessThan) { + + if(value < root->val) { // left + root->less++; + if(root->left == NULL) { + root->left = new BinarySearchTreeNode(value); + }else{ + this->insert(root->left, value, numLessThan); + } + } else if(value > root->val) { // right + numLessThan += root->less + root->count; + if(!root->right) { + root->right = new BinarySearchTreeNode(value); + }else{ + this->insert(root->right, value, numLessThan); + } + } else { + numLessThan += root->less; + root->count++; + return; + } + } +}; + +class Solution { + public: + vector countSmaller(vector& nums) { + vector counts(nums.size()); + if(nums.size() == 0) return counts; + + BinarySearchTree tree(nums[nums.size()-1]); + + for(int i = nums.size() - 2; i >= 0; i--) { + int numLessThan = 0; + tree.insert( nums[i], numLessThan); + counts[i] = numLessThan; + } + return counts; + } +}; From b430d99d3bbd9c57b8b11b548a88b58fafb0d5c9 Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Fri, 15 Jan 2016 22:42:31 +0800 Subject: [PATCH 15/29] New Problem "Count of Range Sum" --- README.md | 1 + .../cpp/countOfRangeSum/CountOfRangeSum.cpp | 163 ++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 algorithms/cpp/countOfRangeSum/CountOfRangeSum.cpp diff --git a/README.md b/README.md index cfee4ebf2..c4c976e14 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ LeetCode | # | Title | Solution | Difficulty | |---| ----- | -------- | ---------- | +|327|[Count of Range Sum](https://leetcode.com/problems/count-of-range-sum/) | [C++](./algorithms/cpp/countOfRangeSum/CountOfRangeSum.cpp)|Hard| |326|[Power of Three](https://leetcode.com/problems/power-of-three/) | [C++](./algorithms/cpp/powerOfThree/PowerOfThree.cpp)|Easy| |322|[Coin Change](https://leetcode.com/problems/coin-change/) | [C++](./algorithms/cpp/coinChange/coinChange.cpp)|Medium| |319|[Bulb Switcher](https://leetcode.com/problems/bulb-switcher/) | [C++](./algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp)|Medium| diff --git a/algorithms/cpp/countOfRangeSum/CountOfRangeSum.cpp b/algorithms/cpp/countOfRangeSum/CountOfRangeSum.cpp new file mode 100644 index 000000000..81b1f21bb --- /dev/null +++ b/algorithms/cpp/countOfRangeSum/CountOfRangeSum.cpp @@ -0,0 +1,163 @@ +// Source : https://leetcode.com/problems/count-of-range-sum/ +// Author : Hao Chen +// Date : 2016-01-15 + +/*************************************************************************************** + * + * Given an integer array nums, return the number of range sums that lie in [lower, + * upper] inclusive. + * + * Range sum S(i, j) is defined as the sum of the elements in nums between indices + * i and + * j (i ≤ j), inclusive. + * + * Note: + * A naive algorithm of O(n2) is trivial. You MUST do better than that. + * + * Example: + * Given nums = [-2, 5, -1], lower = -2, upper = 2, + * Return 3. + * The three ranges are : [0, 0], [2, 2], [0, 2] and their respective sums are: -2, -1, 2. + * + * Credits:Special thanks to @dietpepsi for adding this problem and creating all test + * cases. + * + ***************************************************************************************/ + + +/* + * At first of all, we can do preprocess to calculate the prefix sums + * + * S[i] = S(0, i), then S(i, j) = S[j] - S[i]. + * + * Note: S(i, j) as the sum of range [i, j) where j exclusive and j > i. + * + * With these prefix sums, it is trivial to see that with O(n^2) time we can find all S(i, j) + * in the range [lower, upper] + * + * int countRangeSum(vector& nums, int lower, int upper) { + * int n = nums.size(); + * long[] sums = new long[n + 1]; + * for (int i = 0; i < n; ++i) { + * sums[i + 1] = sums[i] + nums[i]; + * } + * int ans = 0; + * for (int i = 0; i < n; ++i) { + * for (int j = i + 1; j <= n; ++j) { + * if (sums[j] - sums[i] >= lower && sums[j] - sums[i] <= upper) { + * ans++; + * } + * } + * } + * delete []sums; + * return ans; + * } + * + * The above solution would get time limit error. + * + * Recall `count smaller number after self` where we encountered the problem + * + * count[i] = count of nums[j] - nums[i] < 0 with j > i + * + * Here, after we did the preprocess, we need to solve the problem + * + * count[i] = count of a <= S[j] - S[i] <= b with j > i + * + * In other words, if we maintain the prefix sums sorted, and then are able to find out + * - how many of the sums are less than 'lower', say num1, + * - how many of the sums are less than 'upper + 1', say num2, + * Then 'num2 - num1' is the number of sums that lie within the range of [lower, upper]. + * + */ + +class Node{ + public: + long long val; + int cnt; //amount of the nodes + Node *left, *right; + Node(long long v):val(v), cnt(1), left(NULL), right(NULL) {} +}; + +// a tree stores all of prefix sums +class Tree{ + public: + Tree():root(NULL){ } + ~Tree() { freeTree(root); } + + void Insert(long long val) { + Insert(root, val); + } + int LessThan(long long sum, int val) { + return LessThan(root, sum, val, 0); + } + + private: + Node* root; + + //general binary search tree insert algorithm + void Insert(Node* &root, long long val) { + if (!root) { + root = new Node(val); + return; + } + + root->cnt++; + + if (val < root->val ) { + Insert(root->left, val); + }else if (val > root->val) { + Insert(root->right, val); + } + } + //return how many of the sums less than `val` + // - `sum` is the new sums which hasn't been inserted + // - `val` is the `lower` or `upper+1` + int LessThan(Node* root, long long sum, int val, int res) { + + if (!root) return res; + + if ( sum - root->val < val) { + //if (sum[j, i] < val), which means all of the right branch must be less than `val` + //so we add the amounts of sums in right branch, and keep going the left branch. + res += (root->cnt - (root->left ? root->left->cnt : 0) ); + return LessThan(root->left, sum, val, res); + }else if ( sum - root->val > val) { + //if (sum[j, i] > val), which means all of left brach must be greater than `val` + //so we just keep going the right branch. + return LessThan(root->right, sum, val, res); + }else { + //if (sum[j,i] == val), which means we find the correct place, + //so we just return the the amounts of right branch.] + return res + (root->right ? root->right->cnt : 0); + } + } + void freeTree(Node* root){ + if (!root) return; + if (root->left) freeTree(root->left); + if (root->right) freeTree(root->right); + delete root; + } + +}; + + + +class Solution { +public: + int countRangeSum(vector& nums, int lower, int upper) { + Tree tree; + tree.Insert(0); + long long sum = 0; + int res = 0; + + for (int n : nums) { + sum += n; + int lcnt = tree.LessThan(sum, lower); + int hcnt = tree.LessThan(sum, upper + 1); + res += (hcnt - lcnt); + tree.Insert(sum); + } + + return res; + } +}; From b40ca7942d9b2d1fd711b8e5cbd2b5e8007975d3 Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Fri, 15 Jan 2016 22:42:31 +0800 Subject: [PATCH 16/29] New Problem "Count of Range Sum" --- README.md | 1 + .../cpp/countOfRangeSum/CountOfRangeSum.cpp | 163 ++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 algorithms/cpp/countOfRangeSum/CountOfRangeSum.cpp diff --git a/README.md b/README.md index cfee4ebf2..c4c976e14 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ LeetCode | # | Title | Solution | Difficulty | |---| ----- | -------- | ---------- | +|327|[Count of Range Sum](https://leetcode.com/problems/count-of-range-sum/) | [C++](./algorithms/cpp/countOfRangeSum/CountOfRangeSum.cpp)|Hard| |326|[Power of Three](https://leetcode.com/problems/power-of-three/) | [C++](./algorithms/cpp/powerOfThree/PowerOfThree.cpp)|Easy| |322|[Coin Change](https://leetcode.com/problems/coin-change/) | [C++](./algorithms/cpp/coinChange/coinChange.cpp)|Medium| |319|[Bulb Switcher](https://leetcode.com/problems/bulb-switcher/) | [C++](./algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp)|Medium| diff --git a/algorithms/cpp/countOfRangeSum/CountOfRangeSum.cpp b/algorithms/cpp/countOfRangeSum/CountOfRangeSum.cpp new file mode 100644 index 000000000..81b1f21bb --- /dev/null +++ b/algorithms/cpp/countOfRangeSum/CountOfRangeSum.cpp @@ -0,0 +1,163 @@ +// Source : https://leetcode.com/problems/count-of-range-sum/ +// Author : Hao Chen +// Date : 2016-01-15 + +/*************************************************************************************** + * + * Given an integer array nums, return the number of range sums that lie in [lower, + * upper] inclusive. + * + * Range sum S(i, j) is defined as the sum of the elements in nums between indices + * i and + * j (i ≤ j), inclusive. + * + * Note: + * A naive algorithm of O(n2) is trivial. You MUST do better than that. + * + * Example: + * Given nums = [-2, 5, -1], lower = -2, upper = 2, + * Return 3. + * The three ranges are : [0, 0], [2, 2], [0, 2] and their respective sums are: -2, -1, 2. + * + * Credits:Special thanks to @dietpepsi for adding this problem and creating all test + * cases. + * + ***************************************************************************************/ + + +/* + * At first of all, we can do preprocess to calculate the prefix sums + * + * S[i] = S(0, i), then S(i, j) = S[j] - S[i]. + * + * Note: S(i, j) as the sum of range [i, j) where j exclusive and j > i. + * + * With these prefix sums, it is trivial to see that with O(n^2) time we can find all S(i, j) + * in the range [lower, upper] + * + * int countRangeSum(vector& nums, int lower, int upper) { + * int n = nums.size(); + * long[] sums = new long[n + 1]; + * for (int i = 0; i < n; ++i) { + * sums[i + 1] = sums[i] + nums[i]; + * } + * int ans = 0; + * for (int i = 0; i < n; ++i) { + * for (int j = i + 1; j <= n; ++j) { + * if (sums[j] - sums[i] >= lower && sums[j] - sums[i] <= upper) { + * ans++; + * } + * } + * } + * delete []sums; + * return ans; + * } + * + * The above solution would get time limit error. + * + * Recall `count smaller number after self` where we encountered the problem + * + * count[i] = count of nums[j] - nums[i] < 0 with j > i + * + * Here, after we did the preprocess, we need to solve the problem + * + * count[i] = count of a <= S[j] - S[i] <= b with j > i + * + * In other words, if we maintain the prefix sums sorted, and then are able to find out + * - how many of the sums are less than 'lower', say num1, + * - how many of the sums are less than 'upper + 1', say num2, + * Then 'num2 - num1' is the number of sums that lie within the range of [lower, upper]. + * + */ + +class Node{ + public: + long long val; + int cnt; //amount of the nodes + Node *left, *right; + Node(long long v):val(v), cnt(1), left(NULL), right(NULL) {} +}; + +// a tree stores all of prefix sums +class Tree{ + public: + Tree():root(NULL){ } + ~Tree() { freeTree(root); } + + void Insert(long long val) { + Insert(root, val); + } + int LessThan(long long sum, int val) { + return LessThan(root, sum, val, 0); + } + + private: + Node* root; + + //general binary search tree insert algorithm + void Insert(Node* &root, long long val) { + if (!root) { + root = new Node(val); + return; + } + + root->cnt++; + + if (val < root->val ) { + Insert(root->left, val); + }else if (val > root->val) { + Insert(root->right, val); + } + } + //return how many of the sums less than `val` + // - `sum` is the new sums which hasn't been inserted + // - `val` is the `lower` or `upper+1` + int LessThan(Node* root, long long sum, int val, int res) { + + if (!root) return res; + + if ( sum - root->val < val) { + //if (sum[j, i] < val), which means all of the right branch must be less than `val` + //so we add the amounts of sums in right branch, and keep going the left branch. + res += (root->cnt - (root->left ? root->left->cnt : 0) ); + return LessThan(root->left, sum, val, res); + }else if ( sum - root->val > val) { + //if (sum[j, i] > val), which means all of left brach must be greater than `val` + //so we just keep going the right branch. + return LessThan(root->right, sum, val, res); + }else { + //if (sum[j,i] == val), which means we find the correct place, + //so we just return the the amounts of right branch.] + return res + (root->right ? root->right->cnt : 0); + } + } + void freeTree(Node* root){ + if (!root) return; + if (root->left) freeTree(root->left); + if (root->right) freeTree(root->right); + delete root; + } + +}; + + + +class Solution { +public: + int countRangeSum(vector& nums, int lower, int upper) { + Tree tree; + tree.Insert(0); + long long sum = 0; + int res = 0; + + for (int n : nums) { + sum += n; + int lcnt = tree.LessThan(sum, lower); + int hcnt = tree.LessThan(sum, upper + 1); + res += (hcnt - lcnt); + tree.Insert(sum); + } + + return res; + } +}; From eb58453db5801615133c36965e77bad0f803b302 Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Sat, 16 Jan 2016 21:02:16 +0800 Subject: [PATCH 17/29] filter out the blank line --- scripts/comments.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/comments.sh b/scripts/comments.sh index 1d518fe24..69a6a10b6 100755 --- a/scripts/comments.sh +++ b/scripts/comments.sh @@ -160,14 +160,14 @@ fi # 2) the last two `sed` commands are used to add the comments tags case $FILE_EXT in .cpp ) xidel ${leetcode_url} -q -e "css('div.question-content')" | \ - grep -v ' ' | sed '/^$/N;/^\n$/D' | fold -w 85 -s |\ + grep -v ' ' | sed '/^$/N;/^\n$/D' | fold -w 85 -s |\ sed 's/^/ * /' | sed '1i\'$'\n'"/*$(printf '%.0s*' {0..85}) "$'\n' |\ sed '2i\'$'\n''!@#$%'$'\n' | sed 's/!@#$%/ */' | \ sed '$a\'$'\n'"*$(printf '%.0s*' {0..85})*/"$'\n'| \ sed 's/^*/ /' > /tmp/tmp.txt ;; .sh ) xidel ${leetcode_url} -q -e "css('div.question-content')" | \ - grep -v ' ' |sed '/^$/N;/^\n$/D' | fold -w 85 -s| \ + grep -v ' ' |sed '/^$/N;/^\n$/D' | fold -w 85 -s| \ sed 's/^/# /' | sed '1i\'$'\n'"#$(printf '%.0s#' {0..85}) "$'\n' | \ sed '2i\'$'\n''#'$'\n' | sed '$a\'$'\n'"#$(printf '%.0s#' {0..85})"$'\n'\ > /tmp/tmp.txt From e3b71eed8590fe9d1571d25f1cad00a34a60ea9a Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Sat, 16 Jan 2016 21:04:17 +0800 Subject: [PATCH 18/29] New Problem "Expression Add Operators" --- .../ExpressionAddOperators.cpp | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 algorithms/cpp/expressionAddOperators/ExpressionAddOperators.cpp diff --git a/algorithms/cpp/expressionAddOperators/ExpressionAddOperators.cpp b/algorithms/cpp/expressionAddOperators/ExpressionAddOperators.cpp new file mode 100644 index 000000000..573d4fd26 --- /dev/null +++ b/algorithms/cpp/expressionAddOperators/ExpressionAddOperators.cpp @@ -0,0 +1,81 @@ +// Source : https://leetcode.com/problems/expression-add-operators/ +// Author : Hao Chen +// Date : 2016-01-16 + +/*************************************************************************************** + * + * Given a string that contains only digits 0-9 and a target value, return all + * possibilities to add binary operators (not unary) +, -, or * between the digits so + * they evaluate to the target value. + * + * Examples: + * "123", 6 -> ["1+2+3", "1*2*3"] + * "232", 8 -> ["2*3+2", "2+3*2"] + * "105", 5 -> ["1*0+5","10-5"] + * "00", 0 -> ["0+0", "0-0", "0*0"] + * "3456237490", 9191 -> [] + * + * Credits:Special thanks to @davidtan1890 for adding this problem and creating all + * test cases. + ***************************************************************************************/ + + +class Solution { +public: + vector addOperators(string num, int target) { + vector result; + if (num.size() == 0) return result; + helper(num, target, result, "", 0, 0, 0, ' '); + return result; + } + + //DFS algorithm + void helper(const string &num, const int target, //`num` and `target` never change + vector& result, // the array store all of the answers + string solution, //the current potential answer. + int idx, // the current index of `num` array + long long val, // the current value we calculated so far + long long prev, // the lastest value we used for calculation, which used for operation prioirty adjustment + char preop ) // the latest "+" or "-" operation, which used for operation prioirty adjustment + { + + if (target == val && idx == num.size()){ + result.push_back(solution); + return; + } + if (idx == num.size()) return; + + string n; + long long v=0; + for(int i=idx; i Date: Sat, 16 Jan 2016 21:15:22 +0800 Subject: [PATCH 19/29] update readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c4c976e14..6ed7a7ccc 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ LeetCode |285|[Inorder Successor in BST](https://leetcode.com/problems/inorder-successor-in-bst/) ♥ | [Java](./algorithms/java/src/inorderSuccessorInBST/inorderSuccessorInBST.java)|Medium| |284|[Peeking Iterator](https://leetcode.com/problems/peeking-iterator/) | [C++](./algorithms/cpp/peekingIterator/PeekingIterator.cpp)|Medium| |283|[Move Zeroes](https://leetcode.com/problems/move-zeroes/) | [C++](./algorithms/cpp/moveZeroes/moveZeroes.cpp)|Easy| +|282|[Expression Add Operators](https://leetcode.com/problems/expression-add-operators/) | [C++](./algorithms/cpp/expressionAddOperators/ExpressionAddOperators.cpp)|Hard| |279|[Perfect Squares](https://leetcode.com/problems/perfect-squares/) | [C++](./algorithms/cpp/perfectSquares/PerfectSquares.cpp)|Medium| |278|[First Bad Version](https://leetcode.com/problems/first-bad-version/)| [C++](./algorithms/cpp/firstBadVersion/FirstBadVersion.cpp), [Java](./algorithms/java/src/firstBadVersion/firstBadVersion.java)|Easy| |275|[H-Index II](https://leetcode.com/problems/h-index-ii/)| [C++](./algorithms/cpp/h-Index/h-Index.II.cpp)|Medium| From 1ab20b068dac5d7eff3878ddaa01493719cd81d1 Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Sat, 16 Jan 2016 22:03:01 +0800 Subject: [PATCH 20/29] New Problem "Odd Even Linked List" --- README.md | 1 + .../oddEvenLinkedList/OddEvenLinkedList.cpp | 53 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 algorithms/cpp/oddEvenLinkedList/OddEvenLinkedList.cpp diff --git a/README.md b/README.md index 6ed7a7ccc..42d073936 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ LeetCode | # | Title | Solution | Difficulty | |---| ----- | -------- | ---------- | +|328|[Odd Even Linked List](https://leetcode.com/problems/odd-even-linked-list/) | [C++](./algorithms/cpp/oddEvenLinkedList/OddEvenLinkedList.cpp)|Easy| |327|[Count of Range Sum](https://leetcode.com/problems/count-of-range-sum/) | [C++](./algorithms/cpp/countOfRangeSum/CountOfRangeSum.cpp)|Hard| |326|[Power of Three](https://leetcode.com/problems/power-of-three/) | [C++](./algorithms/cpp/powerOfThree/PowerOfThree.cpp)|Easy| |322|[Coin Change](https://leetcode.com/problems/coin-change/) | [C++](./algorithms/cpp/coinChange/coinChange.cpp)|Medium| diff --git a/algorithms/cpp/oddEvenLinkedList/OddEvenLinkedList.cpp b/algorithms/cpp/oddEvenLinkedList/OddEvenLinkedList.cpp new file mode 100644 index 000000000..6a206978e --- /dev/null +++ b/algorithms/cpp/oddEvenLinkedList/OddEvenLinkedList.cpp @@ -0,0 +1,53 @@ +// Source : https://leetcode.com/problems/odd-even-linked-list/ +// Author : Hao Chen +// Date : 2016-01-16 + +/*************************************************************************************** + * + * Given a singly linked list, group all odd nodes together followed by the even nodes. + * Please note here we are talking about the node number and not the value in the nodes. + * + * You should try to do it in place. The program should run in O(1) space complexity + * and O(nodes) time complexity. + * + * Example: + * Given 1->2->3->4->5->NULL, + * return 1->3->5->2->4->NULL. + * + * Note: + * The relative order inside both the even and odd groups should remain as it was in + * the input. + * The first node is considered odd, the second node even and so on ... + * + * Credits:Special thanks to @aadarshjajodia for adding this problem and creating all + * test cases. + ***************************************************************************************/ + +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * ListNode *next; + * ListNode(int x) : val(x), next(NULL) {} + * }; + */ +class Solution { +public: + ListNode* oddEvenList(ListNode* head) { + if (!head) return head; + ListNode* pOdd = head; + ListNode* p = head->next; + ListNode* pNext = NULL; + while(p && (pNext=p->next)) { + + p->next = pNext->next; + pNext->next = pOdd->next; + pOdd->next = pNext; + + p = p->next; + pOdd = pOdd->next; + + } + return head; + } +}; From 1c8023e53f27cc99b2df4360bd35a0647e490005 Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Sat, 16 Jan 2016 22:45:04 +0800 Subject: [PATCH 21/29] New Problem "Single Number III" --- README.md | 1 + .../cpp/singleNumber/singleNumber.III.cpp | 94 +++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 algorithms/cpp/singleNumber/singleNumber.III.cpp diff --git a/README.md b/README.md index 42d073936..3dfe34ef6 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ LeetCode |268|[Missing Number](https://leetcode.com/problems/missing-number/)| [C++](./algorithms/cpp/missingNumber/MissingNumber.cpp)|Medium| |264|[Ugly Number II](https://leetcode.com/problems/ugly-number-ii/)| [C++](./algorithms/cpp/uglyNumber/UglyNumber.II.cpp)|Medium| |263|[Ugly Number](https://leetcode.com/problems/ugly-number/)| [C++](./algorithms/cpp/uglyNumber/UglyNumber.cpp)|Easy| +|260|[Single Number III](https://leetcode.com/problems/single-number-iii/)| [C++](./argorithms/cpp/singleNumber/singleNumber.III.cpp)|Medium| |258|[Add Digits](https://leetcode.com/problems/add-digits/)| [C++](./algorithms/cpp/addDigits/addDigits.cpp)|Easy| |257|[Binary Tree Paths](https://leetcode.com/problems/binary-tree-paths/)| [C++](./algorithms/cpp/binaryTreePaths/binaryTreePaths.cpp)|Easy| |242|[Valid Anagram](https://leetcode.com/problems/valid-anagram/)| [C++](./algorithms/cpp/anagrams/ValidAnagram.cpp)|Easy| diff --git a/algorithms/cpp/singleNumber/singleNumber.III.cpp b/algorithms/cpp/singleNumber/singleNumber.III.cpp new file mode 100644 index 000000000..d2f86bd52 --- /dev/null +++ b/algorithms/cpp/singleNumber/singleNumber.III.cpp @@ -0,0 +1,94 @@ +// Source : https://leetcode.com/problems/single-number-iii/ +// Author : Hao Chen +// Date : 2016-01-16 + +/*************************************************************************************** + * + * Given an array of numbers nums, in which exactly two elements appear only once and + * all the other elements appear exactly twice. Find the two elements that appear only + * once. + * + * For example: + * + * Given nums = [1, 2, 1, 3, 2, 5], return [3, 5]. + * + * Note: + * + * The order of the result is not important. So in the above example, [5, 3] is also + * correct. + * Your algorithm should run in linear runtime complexity. Could you implement it using + * only constant space complexity? + * + * Credits:Special thanks to @jianchao.li.fighter for adding this problem and creating + * all test cases. + ***************************************************************************************/ + + +/* + * For the problem - only one number appears once when all other numbers appears exactly twice. + * + * We know, we can XOR all of the array elements. Since X^X is zero, and X^0 is X, + * so all of the duplicated number will zero themselves out, and the only number would be the result. + * + * However, this solution cannot be applied directly to finding two numbers that appear once each. + * + * Suppose that these numbers that appear once are X and Y, and all other numbers appear twice. + * If we decide to XOR all the array's elements, the overall result would actually be `X^Y`. + * + * Unfortunately, there is no way to extract J and K out of their XOR. + * + * But since X and Y are different, we are sure that X^Y is different than zero. + * + * This information is valuable in sense that we know pieces of information that differ. + * If we pick up any bit that is 1 in X XOR Y, we can use it as a mask to test each element of the array. + * + * Obviously, that mask will be the discriminator between X and Y - + * + * Only one of them will have value 1 at that particular position. + * + * + * Now that we have the mask with exactly one bit set to 1, we can walk through the array once again. + * + * But this time we are going to maintain two XORed results. + * + * - One for numbers that have bit 1 at the mask's position + * - Another for numbers that have bit 0 at that position + * + * In this way, we are sure that all duplicates will go into the same pile. + * + * But likewise, we are sure that X and Y will go into separate piles. + * + * So, the overall result is that + * - the first XORed result will be equal to X + * - and the second XORed result will be equal to Y + * +*/ + +class Solution { +public: + vector singleNumber(vector& nums) { + int allxor = 0; + for (int n : nums) { + allxor ^= n; + } + int mask = 1; + while ( (mask & allxor) == 0 ) { + mask <<= 1; + } + + int zero = 0; + int one = 0; + for (int n : nums) { + if (n & mask ){ + one ^= n; + }else { + zero ^= n; + } + } + + vector result; + result.push_back(zero); + result.push_back(one); + return result; + } +}; From 0d9585f087581fe693abe7075764ebc372e3382c Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Sat, 16 Jan 2016 22:46:37 +0800 Subject: [PATCH 22/29] link error --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3dfe34ef6..aa2f240c2 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ LeetCode |268|[Missing Number](https://leetcode.com/problems/missing-number/)| [C++](./algorithms/cpp/missingNumber/MissingNumber.cpp)|Medium| |264|[Ugly Number II](https://leetcode.com/problems/ugly-number-ii/)| [C++](./algorithms/cpp/uglyNumber/UglyNumber.II.cpp)|Medium| |263|[Ugly Number](https://leetcode.com/problems/ugly-number/)| [C++](./algorithms/cpp/uglyNumber/UglyNumber.cpp)|Easy| -|260|[Single Number III](https://leetcode.com/problems/single-number-iii/)| [C++](./argorithms/cpp/singleNumber/singleNumber.III.cpp)|Medium| +|260|[Single Number III](https://leetcode.com/problems/single-number-iii/)| [C++](./algorithms/cpp/singleNumber/singleNumber.III.cpp)|Medium| |258|[Add Digits](https://leetcode.com/problems/add-digits/)| [C++](./algorithms/cpp/addDigits/addDigits.cpp)|Easy| |257|[Binary Tree Paths](https://leetcode.com/problems/binary-tree-paths/)| [C++](./algorithms/cpp/binaryTreePaths/binaryTreePaths.cpp)|Easy| |242|[Valid Anagram](https://leetcode.com/problems/valid-anagram/)| [C++](./algorithms/cpp/anagrams/ValidAnagram.cpp)|Easy| From 1f24b4a199f7cae2a9f46d0b915f72d1b0ef28b5 Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Sun, 17 Jan 2016 16:12:12 +0800 Subject: [PATCH 23/29] New Problem "Burst Balloons" --- README.md | 1 + .../cpp/burstBalloons/BurstBalloons.cpp | 104 ++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 algorithms/cpp/burstBalloons/BurstBalloons.cpp diff --git a/README.md b/README.md index aa2f240c2..6a9945f68 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ LeetCode |322|[Coin Change](https://leetcode.com/problems/coin-change/) | [C++](./algorithms/cpp/coinChange/coinChange.cpp)|Medium| |319|[Bulb Switcher](https://leetcode.com/problems/bulb-switcher/) | [C++](./algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp)|Medium| |315|[Count of Smaller Numbers After Self](https://leetcode.com/problems/count-of-smaller-numbers-after-self/) | [C++](./algorithms/cpp/countOfSmallerNumbersAfterSelf/countOfSmallerNumbersAfterSelf.cpp)|Hard| +|312|[Burst Balloons](https://leetcode.com/problems/burst-balloons/) | [C++](./algorithms/cpp/burstBalloons/BurstBalloons.cpp)|Hard| |307|[Range Sum Query - Mutable](https://leetcode.com/problems/range-sum-query-mutable/) | [C++](./algorithms/cpp/rangeSumQuery-Immutable/rangeSumQuery-Mutable/RangeSumQueryMutable.cpp)|Medium| |306|[Additive Number](https://leetcode.com/problems/additive-number/) | [C++](./algorithms/cpp/additiveNumber/AdditiveNumber.cpp)|Medium| |304|[Range Sum Query 2D - Immutable](https://leetcode.com/problems/range-sum-query-2d-immutable/) | [C++](./algorithms/cpp/rangeSumQuery2D-Immutable/RangeSumQuery2dImmutable.cpp)|Medium| diff --git a/algorithms/cpp/burstBalloons/BurstBalloons.cpp b/algorithms/cpp/burstBalloons/BurstBalloons.cpp new file mode 100644 index 000000000..901f2e8eb --- /dev/null +++ b/algorithms/cpp/burstBalloons/BurstBalloons.cpp @@ -0,0 +1,104 @@ +// Source : https://leetcode.com/problems/burst-balloons/ +// Author : Hao Chen +// Date : 2016-01-17 + +/*************************************************************************************** + * + * Given n balloons, indexed from 0 to n-1. Each balloon is painted with a + * number on it represented by array nums. + * + * You are asked to burst all the balloons. If the you burst + * balloon i you will get nums[left] * nums[i] * nums[right] coins. Here left + * and right are adjacent indices of i. After the burst, the left and right + * then becomes adjacent. + * + * Find the maximum coins you can collect by bursting the balloons wisely. + * + * Note: + * (1) You may imagine nums[-1] = nums[n] = 1. They are not real therefore you can + * not burst them. + * (2) 0 ≤ n ≤ 500, 0 ≤ nums[i] ≤ 100 + * + * Example: + * + * Given [3, 1, 5, 8] + * + * Return 167 + * + * nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> [] + * coins = 3*1*5 + 3*5*8 + 1*3*8 + 1*8*1 = 167 + * + * Credits:Special thanks to @dietpepsi for adding this problem and creating all test + * cases. + ***************************************************************************************/ + + + +class Solution { +public: + int maxCoins(vector& nums) { + //remove all of zero item + nums.erase(remove_if(nums.begin(), nums.end(), [](int n){return n==0;}), nums.end()); + + //add 1 for head and tail + nums.insert(nums.begin(),1); + nums.push_back(1); + + int n = nums.size(); + vector< vector > matrix(n, vector(n,0)); + + return maxCoins_DP(nums, matrix); + return maxCoins_DC(nums, matrix, 0, n-1); + } + + + //Divide and Conquer + // + // If we seprate the array to two part, left part and right part. + // + // Then, we will find in this problem the left and right become adjacent + // and have effects on the maxCoins in the future. + // + // So, if we think reversely, if the balloon i is the last balloon of all to burst, + // the left and right section now has well defined boundary and do not affect each other! + // Therefore we can do either recursive method with memoization + // + int maxCoins_DC(vector& nums, vector>& matrix, int low, int high) { + if (low + 1 == high) return 0; + if (matrix[low][high] > 0) return matrix[low][high]; + int result = 0; + for (int i = low + 1; i < high; ++i){ + result = max(result, nums[low] * nums[i] * nums[high] + + maxCoins_DC(nums, matrix, low, i) + + maxCoins_DC(nums, matrix, i, high)); + } + matrix[low][high] = result; + return result; + } + + //Dynamic Programming + // + // using the same idea of above + // + int maxCoins_DP(vector& nums, vector>& dp) { + int n = nums.size(); + for (int k = 2; k < n; ++k) { + for (int low = 0; low < n - k; low++){ + int high = low + k; + for (int i = low + 1; i < high; ++i) + dp[low][high] = max( dp[low][high], + nums[low] * nums[i] * nums[high] + dp[low][i] + dp[i][high]); + } + } + return dp[0][n - 1]; + } + +private: + void printVector(vector& nums) { + cout << "nums: "; + for (auto n: nums) { + cout << n << ' '; + } + cout << '\n'; + } +}; From 53fe7c9cac47b32b6ee11b6d90193738f100cd45 Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Thu, 21 Jan 2016 15:13:39 +0800 Subject: [PATCH 24/29] New Problem "Create Maximum Number" --- README.md | 1 + .../CreateMaximumNumber.cpp | 152 ++++++++++++++++++ 2 files changed, 153 insertions(+) create mode 100644 algorithms/cpp/createMaximumNumber/CreateMaximumNumber.cpp diff --git a/README.md b/README.md index 6a9945f68..6d154e63c 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ LeetCode |327|[Count of Range Sum](https://leetcode.com/problems/count-of-range-sum/) | [C++](./algorithms/cpp/countOfRangeSum/CountOfRangeSum.cpp)|Hard| |326|[Power of Three](https://leetcode.com/problems/power-of-three/) | [C++](./algorithms/cpp/powerOfThree/PowerOfThree.cpp)|Easy| |322|[Coin Change](https://leetcode.com/problems/coin-change/) | [C++](./algorithms/cpp/coinChange/coinChange.cpp)|Medium| +|321|[Create Maximum Number](https://leetcode.com/problems/create-maximum-number/) | [C++](./algorithms/cpp/createMaximumNumber/CreateMaximumNumber.cpp)|Hard| |319|[Bulb Switcher](https://leetcode.com/problems/bulb-switcher/) | [C++](./algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp)|Medium| |315|[Count of Smaller Numbers After Self](https://leetcode.com/problems/count-of-smaller-numbers-after-self/) | [C++](./algorithms/cpp/countOfSmallerNumbersAfterSelf/countOfSmallerNumbersAfterSelf.cpp)|Hard| |312|[Burst Balloons](https://leetcode.com/problems/burst-balloons/) | [C++](./algorithms/cpp/burstBalloons/BurstBalloons.cpp)|Hard| diff --git a/algorithms/cpp/createMaximumNumber/CreateMaximumNumber.cpp b/algorithms/cpp/createMaximumNumber/CreateMaximumNumber.cpp new file mode 100644 index 000000000..dc88f9a41 --- /dev/null +++ b/algorithms/cpp/createMaximumNumber/CreateMaximumNumber.cpp @@ -0,0 +1,152 @@ +// Source : https://leetcode.com/problems/create-maximum-number/ +// Author : Hao Chen +// Date : 2016-01-21 + +/*************************************************************************************** + * + * Given two arrays of length m and n with digits 0-9 representing two numbers. + * Create the maximum number of length k from digits of the two. The relative + * order of the digits + * from the same array must be preserved. Return an array of the k digits. You + * should try to optimize your time and space complexity. + * + * Example 1: + * + * nums1 = [3, 4, 6, 5] + * nums2 = [9, 1, 2, 5, 8, 3] + * k = 5 + * return [9, 8, 6, 5, 3] + * + * Example 2: + * + * nums1 = [6, 7] + * nums2 = [6, 0, 4] + * k = 5 + * return [6, 7, 6, 0, 4] + * + * Example 3: + * + * nums1 = [3, 9] + * nums2 = [8, 9] + * k = 3 + * return [9, 8, 9] + * + * Credits:Special thanks to @dietpepsi for adding this problem and creating all test + * cases. + ***************************************************************************************/ + + + +/* + * Solution + * -------- + * + * 1) We split the `K` to two parts : `i` & `k-i` 0<= i <= k + * + * 2) Find the max number for both arrays with giving the length `i` and `k-i` + * - sub1 = FindMaxNumber(num1, len=i); + * - sub2 = FindMaxNumber(num2, len=k-i); + * Here, we need use stack-way to solve find the max number. + * + * 3) Merge two arrays + * - solution = Merge(sub1, sub2); + * Here, we need be careful if a two number are same which one we need to take. For examples: + * [6,7] + * [6,0,4] + * 5 + * + * [2,5,6,4,4,0] + * [7,3,8,0,6,5,7,6,2] + * 15 + * + * 4) compare with the last solution + * - result = max(result, solution); + * + * + */ + + +class Solution { +public: + vector maxNumber(vector& nums1, vector& nums2, int k) { + vector result; + int len1 = nums1.size(); + int len2 = nums2.size(); + for (int i=0; i<=k; i++){ + if (len1 < i || len2 < k-i) continue; + vector sub1 = findMaxSubArray(nums1, i); + vector sub2 = findMaxSubArray(nums2, k-i); + vector merge = mergeTwoArrays(sub1, sub2); + if (compareTwoArray(merge, 0, result, 0)) { + result = merge; + } + } + return result; + } + + + bool compareTwoArray(vector& nums1, int start1, vector& nums2, int start2) { + int n1 = nums1.size(); + int n2 = nums2.size(); + for(; start1 nums2[start2]) return true; + if (nums1[start1] < nums2[start2]) return false; + } + //if num1 still have numbers, return true, else return false + return start1 < nums1.size(); + } + + vector mergeTwoArrays(vector& nums1, vector& nums2) { + vector result; + int len1 = nums1.size(); + int len2 = nums2.size(); + int pos1=0, pos2=0; + while ( pos1 < len1 && pos2 < len2 ){ + // Be careful if two numbers are equal. consider the following case + // case 1: [6,7], [6,0,4] - we have same item - 6 + // case 2: [4,0,2], [2,0,3,1] - we have same item - 0 + // which one we need to merge? + // We need compare the rest of array. + if (nums1[pos1] == nums2[pos2]){ + result.push_back( compareTwoArray(nums1, pos1+1, nums2, pos2+1) ? + nums1[pos1++] : nums2[pos2++]); + }else { + result.push_back(nums1[pos1] > nums2[pos2] ? + nums1[pos1++] : nums2[pos2++]); + } + } + + if (pos1 < len1){ + result.insert(result.end(), nums1.begin()+pos1, nums1.end()); + } + if (pos2 < len2) { + result.insert(result.end(), nums2.begin()+pos2, nums2.end()); + } + + return result; + } + + + // using a stack method to find the max sub-array + // k <= nums.size() + vector findMaxSubArray(vector& nums, int k) { + int len = nums.size(); + if ( k >= len ) return nums; + vector result(k, 0); + int idx = 0; // the postion for result array + for (int i=0; i the last element of result[], + // and we still have enough numbers, + // then pop up the item + while (idx>0 && k - idx < len - i && result[idx-1] < nums[i]) { + idx--; + } + //push the number into the result[] + if (idx < k) { + result[idx++] = nums[i]; + } + } + return result; + } + +}; From 69a1d4b8240ccb64bd456ec26d3452c7cd71669a Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Thu, 21 Jan 2016 23:44:42 +0800 Subject: [PATCH 25/29] New Problem "Longest Increasing Path in a Matrix" --- README.md | 1 + .../LongestIncreasingPathInAMatrix.cpp | 81 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 algorithms/cpp/longestIncreasingPathInAMatrix/LongestIncreasingPathInAMatrix.cpp diff --git a/README.md b/README.md index 6d154e63c..8762d1e84 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ LeetCode | # | Title | Solution | Difficulty | |---| ----- | -------- | ---------- | +|329|[Longest Increasing Path in a Matrix](https://leetcode.com/problems/longest-increasing-path-in-a-matrix/) | [C++](./algorithms/cpp/longestIncreasingPathInAMatrix/LongestIncreasingPathInAMatrix.cpp)|Medium| |328|[Odd Even Linked List](https://leetcode.com/problems/odd-even-linked-list/) | [C++](./algorithms/cpp/oddEvenLinkedList/OddEvenLinkedList.cpp)|Easy| |327|[Count of Range Sum](https://leetcode.com/problems/count-of-range-sum/) | [C++](./algorithms/cpp/countOfRangeSum/CountOfRangeSum.cpp)|Hard| |326|[Power of Three](https://leetcode.com/problems/power-of-three/) | [C++](./algorithms/cpp/powerOfThree/PowerOfThree.cpp)|Easy| diff --git a/algorithms/cpp/longestIncreasingPathInAMatrix/LongestIncreasingPathInAMatrix.cpp b/algorithms/cpp/longestIncreasingPathInAMatrix/LongestIncreasingPathInAMatrix.cpp new file mode 100644 index 000000000..a7e6a4423 --- /dev/null +++ b/algorithms/cpp/longestIncreasingPathInAMatrix/LongestIncreasingPathInAMatrix.cpp @@ -0,0 +1,81 @@ +// Source : https://leetcode.com/problems/longest-increasing-path-in-a-matrix/ +// Author : Hao Chen +// Date : 2016-01-21 + +/*************************************************************************************** + * + * Given an integer matrix, find the length of the longest increasing path. + * + * From each cell, you can either move to four directions: left, right, up or down. You + * may NOT move diagonally or move outside of the boundary (i.e. wrap-around is not + * allowed). + * + * Example 1: + * + * nums = [ + * [>9, 9, 4], + * [>6, 6, 8], + * [>2,>1, 1] + * ] + * + * Return 4 + * + * The longest increasing path is [1, 2, 6, 9]. + * + * Example 2: + * + * nums = [ + * [>3,>4,>5], + * [ 3, 2,>6], + * [ 2, 2, 1] + * ] + * + * Return 4 + * + * The longest increasing path is [3, 4, 5, 6]. Moving diagonally is not allowed. + * + * Credits:Special thanks to @dietpepsi for adding this problem and creating all test + * cases. + ***************************************************************************************/ + + +class Solution { +public: + int longestIncreasingPath(vector>& matrix) { + int result = 0; + int row = matrix.size(); + int col = row ? matrix[0].size() : 0; + vector> path = vector>(row, vector(col, 0)); + for (int r = 0; r < row; r++) { + for (int c = 0; c < col; c++) { + result = max(result, helper(matrix, path, row, col, r, c)); + } + } + return result; + } + + int helper(vector>& matrix, vector>& path, const int row, const int col, int r, int c) { + + if (path[r][c]>0) return path[r][c]; + + int maxPath = 0; + + int tmp = matrix[r][c]; + matrix[r][c]=INT_MIN; + if (r < row-1 && tmp < matrix[r+1][c]) { + maxPath = max(maxPath, helper(matrix, path, row, col, r+1, c)); + } + if (c < col-1 && tmp < matrix[r][c+1]) { + maxPath = max(maxPath, helper(matrix, path, row, col, r, c+1)); + } + if (r > 0 && tmp < matrix[r-1][c]) { + maxPath = max(maxPath, helper(matrix, path, row, col, r-1, c)); + } + if (c > 0 && tmp < matrix[r][c-1]) { + maxPath = max(maxPath, helper(matrix, path, row, col, r, c-1)); + } + matrix[r][c] = tmp; + path[r][c] = maxPath + 1; + return path[r][c]; + } +}; From 50b9b4ee87d1f0c4cba69c428a7f4ff81d550c19 Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Sun, 24 Jan 2016 15:27:08 +0800 Subject: [PATCH 26/29] New Problem "Minimum Height Trees" --- README.md | 1 + .../minimumHeightTrees/MinimumHeightTrees.cpp | 98 +++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 algorithms/cpp/minimumHeightTrees/MinimumHeightTrees.cpp diff --git a/README.md b/README.md index 8762d1e84..6d410f75a 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ LeetCode |319|[Bulb Switcher](https://leetcode.com/problems/bulb-switcher/) | [C++](./algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp)|Medium| |315|[Count of Smaller Numbers After Self](https://leetcode.com/problems/count-of-smaller-numbers-after-self/) | [C++](./algorithms/cpp/countOfSmallerNumbersAfterSelf/countOfSmallerNumbersAfterSelf.cpp)|Hard| |312|[Burst Balloons](https://leetcode.com/problems/burst-balloons/) | [C++](./algorithms/cpp/burstBalloons/BurstBalloons.cpp)|Hard| +|310|[Minimum Height Trees](https://leetcode.com/problems/minimum-height-trees/) | [C++](./algorithms/cpp/minimumHeightTrees/MinimumHeightTrees.cpp)|Medium| |307|[Range Sum Query - Mutable](https://leetcode.com/problems/range-sum-query-mutable/) | [C++](./algorithms/cpp/rangeSumQuery-Immutable/rangeSumQuery-Mutable/RangeSumQueryMutable.cpp)|Medium| |306|[Additive Number](https://leetcode.com/problems/additive-number/) | [C++](./algorithms/cpp/additiveNumber/AdditiveNumber.cpp)|Medium| |304|[Range Sum Query 2D - Immutable](https://leetcode.com/problems/range-sum-query-2d-immutable/) | [C++](./algorithms/cpp/rangeSumQuery2D-Immutable/RangeSumQuery2dImmutable.cpp)|Medium| diff --git a/algorithms/cpp/minimumHeightTrees/MinimumHeightTrees.cpp b/algorithms/cpp/minimumHeightTrees/MinimumHeightTrees.cpp new file mode 100644 index 000000000..9f3a125f2 --- /dev/null +++ b/algorithms/cpp/minimumHeightTrees/MinimumHeightTrees.cpp @@ -0,0 +1,98 @@ +// Source : https://leetcode.com/problems/minimum-height-trees/ +// Author : Hao Chen +// Date : 2016-01-24 + +/*************************************************************************************** + * + * For a undirected graph with tree characteristics, we can choose any node as the + * root. The result graph is then a rooted tree. Among all possible rooted trees, those + * with minimum height are called minimum height trees (MHTs). + * + * Given such a graph, write a function to find all the MHTs and return a list of + * their root labels. + * + * *Format* + * The graph contains n nodes which are labeled from 0 to n - 1. + * You will be given the number n and a list of undirected edges (each edge is a + * pair of labels). + * + * + * You can assume that no duplicate edges will appear in edges. Since all edges are + * undirected, [0, 1] is the same as [1, 0] and thus will not appear together in edges. + * + * Example 1: + * + * Given n = 4, edges = [[1, 0], [1, 2], [1, 3]] + * + * 0 + * | + * 1 + * / \ + * 2 3 + * + * return [1] + * + * Example 2: + * + * Given n = 6, edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]] + * + * 0 1 2 + * \ | / + * 3 + * | + * 4 + * | + * 5 + * + * return [3, 4] + * + * How many MHTs can a graph have at most? + * + * Note: + * + * (1) According to the definition of tree on Wikipedia: https://en.wikipedia.org/wiki/Tree_(graph_theory) + * “a tree is an undirected graph in which any two vertices are connected by exactly one path. + * In other words, any connected graph without simple cycles is a tree.” + * + * (2) The height of a rooted tree is the number of edges on the longest downward path between + * the root and a leaf. + * + * Credits:Special thanks to @dietpepsi for adding this problem and creating all test + * cases. + ***************************************************************************************/ + +class Solution { +public: + vector findMinHeightTrees(int n, vector>& edges) { + //corner case + if ( n <= 1 ) return {0}; + + //construct a edges search data stucture + vector> graph(n); + for (auto e : edges) { + graph[e.first].insert(e.second); + graph[e.second].insert(e.first); + } + + //find all of leaf nodes + vector current; + for (int i=0; i next; + for (int node : current) { + for (int neighbor : graph[node]) { + graph[neighbor].erase(node); + if (graph[neighbor].size() == 1) next.push_back(neighbor); + } + } + if (next.empty()) break; + current = next; + } + return current; + } + +}; From e594f51689888f6b8d836b5631ec39997c80b3e1 Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Mon, 25 Jan 2016 14:53:39 +0800 Subject: [PATCH 27/29] another solution for "Bulb Switcher" --- algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp | 38 +++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp b/algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp index 04b046391..d4f51736b 100644 --- a/algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp +++ b/algorithms/cpp/bulbSwitcher/bulbSwitcher.cpp @@ -1,5 +1,5 @@ // Source : https://leetcode.com/problems/bulb-switcher/ -// Author : Calinescu Valentin +// Author : Calinescu Valentin, Hao Chen // Date : 2015-12-28 /*************************************************************************************** @@ -21,6 +21,42 @@ * So you should return 1, because there is only one bulb is on. * ***************************************************************************************/ + + /* Solution + * -------- + * + * We know, + * - if a bulb can be switched to ON eventually, it must be switched by ODD times + * - Otherwise, if a bulb has been switched by EVEN times, it will be OFF eventually. + * So, + * - If bulb `i` ends up ON if and only if `i` has an ODD numbers of divisors. + * And we know, + * - the divisors come in pairs. for example: + * 12 - [1,12] [2,6] [3,4] [6,2] [12,1] (the 12th bulb would be switched by 1,2,3,4,6,12) + * - the pairs means almost all of the numbers are switched by EVEN times. + * + * But we have a special case - square numbers + * - A square number must have a divisors pair with same number. such as 4 - [2,2], 9 - [3,3] + * - So, a square number has a ODD numbers of divisors. + * + * At last, we figure out the solution is: + * + * Count the number of the squre numbers!! + */ + +class Solution { +public: + int bulbSwitch(int n) { + int cnt = 0; + for (int i=1; i*i<=n; i++) { + cnt++; + } + return cnt; + } +}; + + + /* * Solution 1 - O(1) * ========= From 8469352740f8b23e0d1234af8d88d75ba0a81ebf Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Tue, 26 Jan 2016 23:25:41 +0800 Subject: [PATCH 28/29] another implementation for "Coin Change" --- algorithms/cpp/coinChange/coinChange.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/algorithms/cpp/coinChange/coinChange.cpp b/algorithms/cpp/coinChange/coinChange.cpp index e8ddc9c51..2b7d9b296 100644 --- a/algorithms/cpp/coinChange/coinChange.cpp +++ b/algorithms/cpp/coinChange/coinChange.cpp @@ -1,5 +1,5 @@ // Source : https://leetcode.com/problems/coin-change/ -// Author : Calinescu Valentin +// Author : Calinescu Valentin, Hao Chen // Date : 2015-12-28 /*************************************************************************************** @@ -60,3 +60,24 @@ class Solution { return -1; } }; + + +//Another DP implmentation, same idea above +class Solution { +public: + int coinChange(vector& coins, int amount) { + const int MAX = amount +1; + vector dp(amount+1, MAX); + dp[0]=0; + + for(int i=1; i<=amount; i++) { + for (int j=0; j= coins[j]) { + dp[i] = min( dp[i], dp[i-coins[j]] + 1 ); + } + } + } + + return dp[amount]==MAX ? -1 : dp[amount]; + } +}; From 79a570c0f246b067f54bccc881420daf2ff4d863 Mon Sep 17 00:00:00 2001 From: Hao Chen Date: Wed, 27 Jan 2016 00:07:13 +0800 Subject: [PATCH 29/29] another solution for "Longest Increasing Subsequence" --- .../longestIncreasingSubsequence.cpp | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/algorithms/cpp/longestIncreasingSubsequence/longestIncreasingSubsequence.cpp b/algorithms/cpp/longestIncreasingSubsequence/longestIncreasingSubsequence.cpp index 70a7fadab..30c65e9f4 100644 --- a/algorithms/cpp/longestIncreasingSubsequence/longestIncreasingSubsequence.cpp +++ b/algorithms/cpp/longestIncreasingSubsequence/longestIncreasingSubsequence.cpp @@ -1,5 +1,5 @@ // Source : https://leetcode.com/problems/longest-increasing-subsequence/ -// Author : Calinescu Valentin +// Author : Calinescu Valentin, Hao Chen // Date : 2015-11-06 /*************************************************************************************** @@ -22,6 +22,30 @@ * ***************************************************************************************/ + + +// O(n^2) - dynamic programming +class Solution { +public: + int lengthOfLIS(vector& nums) { + + int len = nums.size(); + int maxLen = 0; + vector dp(len, 1); + + for (int i=0; i