From a41da1a31f4387a2a7618210a40d14e282c71b77 Mon Sep 17 00:00:00 2001 From: Shichao An Date: Sun, 29 Mar 2015 16:30:32 -0700 Subject: [PATCH 01/35] Refactored bash script --- makedir.sh | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/makedir.sh b/makedir.sh index 7b9dd4e..3dd7ca1 100755 --- a/makedir.sh +++ b/makedir.sh @@ -1,13 +1,20 @@ #!/bin/bash -usage="./makedir.sh title [...]" -[ "$#" -eq 0 ] && { echo "$usage"; exit 1; } +USAGE="./makedir.sh title [...]" -scriptdir=$(dirname "$0") -newdir="$scriptdir/$(echo "$@" | tr 'A-Z ' 'a-z_' | tr -d "'")" +[ "$#" -eq 0 ] && { + echo "$USAGE" + exit 1 +} -[ -d "$newdir" ] && { echo "This directory already exists"; exit 1; } +SCRIPTDIR=$(dirname "$0") +NEWDIR="$SCRIPTDIR/$(echo "$@" | tr 'A-Z ' 'a-z_' | tr -d "'")" -echo "Creating new directory $newdir ..." -mkdir "$newdir" -touch "$newdir/solution.py" +[ -d "$NEWDIR" ] && { + echo "This directory already exists" + exit 1 +} + +echo "Creating new directory $NEWDIR ..." +mkdir "$NEWDIR" +touch "$NEWDIR/solution.py" From ffbb1002fd80f995f96c0af6d1137037e0352dba Mon Sep 17 00:00:00 2001 From: Shichao An Date: Wed, 19 Aug 2015 14:20:21 -0700 Subject: [PATCH 02/35] Added alternative solutions to subsets and subsets ii --- subsets/solution3.py | 19 +++++++++++++++++++ subsets/solution4.py | 24 ++++++++++++++++++++++++ subsets_ii/solution2.py | 23 +++++++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 subsets/solution3.py create mode 100644 subsets/solution4.py create mode 100644 subsets_ii/solution2.py diff --git a/subsets/solution3.py b/subsets/solution3.py new file mode 100644 index 0000000..1e0fc89 --- /dev/null +++ b/subsets/solution3.py @@ -0,0 +1,19 @@ +class Solution: + # @param S, a list of integer + # @return a list of lists of integer + def subsets(self, S): + S.sort() + cand = [] + res = [] + self.subsets_aux(S, cand, res) + return res + + def subsets_aux(self, S, cand, res): + res.append(cand[:]) + for i, e in enumerate(S): + cand.append(S[i]) + self.subsets_aux(S[i + 1:], cand, res) + cand.pop() + +s = Solution() +print(s.subsets([1, 2, 3])) diff --git a/subsets/solution4.py b/subsets/solution4.py new file mode 100644 index 0000000..75aa8cd --- /dev/null +++ b/subsets/solution4.py @@ -0,0 +1,24 @@ +# Using bit manipulation +class Solution: + # @param S, a list of integer + # @return a list of lists of integer + def subsets(self, S): + S.sort() + k = len(S) + n = 2 ** k + res = [] + for i in range(n): + s = self.filter(S, k, i) + res.append(s) + return res + + def filter(self, S, k, i): + res = [] + for j in range(k): + mask = 1 << j + if i & mask > 0: + res.append(S[j]) + return res + +s = Solution() +print(s.subsets([1, 2, 3])) diff --git a/subsets_ii/solution2.py b/subsets_ii/solution2.py new file mode 100644 index 0000000..5edb013 --- /dev/null +++ b/subsets_ii/solution2.py @@ -0,0 +1,23 @@ +class Solution: + # @param {integer[]} nums + # @return {integer[][]} + def subsetsWithDup(self, nums): + nums.sort() + return self.subsets_aux(nums) + + def subsets_aux(self, nums): + if not nums: + return [[]] + else: + res = [[]] + for i, e in enumerate(nums): + if i > 0 and nums[i] == nums[i - 1]: + continue + rest_subsets = self.subsets_aux(nums[i + 1:]) + for subset in rest_subsets: + subset.insert(0, e) + res += rest_subsets + return res + +s = Solution() +print s.subsetsWithDup([1, 2, 2]) From a9f9064b4e1adde416a1350da5f9c1a53aa13c43 Mon Sep 17 00:00:00 2001 From: Shichao An Date: Wed, 19 Aug 2015 18:07:08 -0700 Subject: [PATCH 03/35] Added more new problems --- binary_search_tree_iterator/solution.py | 37 +++++++++++++++++++++ number_of_islands/solution.py | 44 +++++++++++++++++++++++++ reverse_bits/solution.py | 26 +++++++++++++++ valid_anagram/solution.py | 25 ++++++++++++++ 4 files changed, 132 insertions(+) create mode 100644 binary_search_tree_iterator/solution.py create mode 100644 number_of_islands/solution.py create mode 100644 reverse_bits/solution.py create mode 100644 valid_anagram/solution.py diff --git a/binary_search_tree_iterator/solution.py b/binary_search_tree_iterator/solution.py new file mode 100644 index 0000000..22d09fe --- /dev/null +++ b/binary_search_tree_iterator/solution.py @@ -0,0 +1,37 @@ +# Definition for a binary tree node +# class TreeNode: +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class BSTIterator: + # @param root, a binary search tree's root node + def __init__(self, root): + self._arr = [] + self._inorder(root) + self._cur = -1 + + # @return a boolean, whether we have a next smallest number + def hasNext(self): + if self._arr[self._cur + 1:]: + return True + return False + + # @return an integer, the next smallest number + def next(self): + if self.hasNext(): + self._cur += 1 + return self._arr[self._cur] + + def _inorder(self, root): + if root is not None: + if root.left is not None: + self._inorder(root.left) + self._arr.append(root.val) + if root.right is not None: + self._inorder(root.right) + +# Your BSTIterator will be called like this: +# i, v = BSTIterator(root), [] +# while i.hasNext(): v.append(i.next()) diff --git a/number_of_islands/solution.py b/number_of_islands/solution.py new file mode 100644 index 0000000..9e55391 --- /dev/null +++ b/number_of_islands/solution.py @@ -0,0 +1,44 @@ +class Solution: + # @param {character[][]} grid + # @return {integer} + def numIslands(self, grid): + self.islands = set() # coordinates of 1s (set of tuples) + res = 0 + n = len(grid) + if n == 0: + return 0 + m = len(grid[0]) + if m == 0: + return 0 + for y in range(n): + for x in range(m): + if grid[y][x] == '1' and (x, y) not in self.islands: + self.probe(grid, x, y, m, n) + res += 1 + return res + + def probe(self, grid, x, y, m, n): + """ + Probe right and down + """ + if x >= m or y >= n: + return + elif grid[y][x] == '0': + return + else: + self.islands.add((x, y)) + self.probe(grid, x + 1, y, m, n) + self.probe(grid, x, y + 1, m, n) + + +g1 = [ + list('11000'), + list('11000'), + list('00100'), + list('00011') +] +for r in g1: + print(r) +s = Solution() +print(s.numIslands(g1)) +print(s.islands) diff --git a/reverse_bits/solution.py b/reverse_bits/solution.py new file mode 100644 index 0000000..295038c --- /dev/null +++ b/reverse_bits/solution.py @@ -0,0 +1,26 @@ +class Solution: + # @param n, an integer + # @return an integer + def reverseBits(self, n): + res = 0 + size = 32 + for i in range(size): + if self.test_bit(n, i): + print(i) + res = self.set_bit(res, size - 1 - i) + return res + + def test_bit(self, n, i): + mask = 1 << i + if n & mask > 0: + return True + return False + + def set_bit(self, n, i): + mask = 1 << i + return n | mask + +s = Solution() +print(bin(43261596)) +res = s.reverseBits(43261596) +print(bin(res)) diff --git a/valid_anagram/solution.py b/valid_anagram/solution.py new file mode 100644 index 0000000..7857150 --- /dev/null +++ b/valid_anagram/solution.py @@ -0,0 +1,25 @@ +class Solution: + # @param {string} s + # @param {string} t + # @return {boolean} + def isAnagram(self, s, t): + if len(s) != len(t): + return False + d = {} + for c in s: + if c in d: + d[c] += 1 + else: + d[c] = 1 + for c in t: + if c not in d: + return False + else: + d[c] -= 1 + if d[c] < 0: + return False + return True + +s = Solution() +print(s.isAnagram("aacc", "ccac")) +print(s.isAnagram("abcd", "bcda")) From 3a809cbb08ba6d775ef621e43f0a34d4ed050bf4 Mon Sep 17 00:00:00 2001 From: Shichao An Date: Wed, 19 Aug 2015 22:49:14 -0700 Subject: [PATCH 04/35] Added restore_ip_addresses --- restore_ip_addresses/solution.py | 48 ++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 restore_ip_addresses/solution.py diff --git a/restore_ip_addresses/solution.py b/restore_ip_addresses/solution.py new file mode 100644 index 0000000..984b058 --- /dev/null +++ b/restore_ip_addresses/solution.py @@ -0,0 +1,48 @@ +""" +Given a string containing only digits, restore it by returning all possible +valid IP address combinations. + +For example: +Given "25525511135", + +return ["255.255.11.135", "255.255.111.35"]. (Order does not matter) +""" + +class Solution: + # @param {string} s + # @return {string[]} + def restoreIpAddresses(self, s): + res = [] + cand = [] + self.restore_ip(s, cand, res) + return res + + def restore_ip(self, s, cand, res): + # If more than 4 parts, or 4 parts already but with remaining + # unprocessed sub-string + if len(cand) > 4 or len(cand) == 4 and s: + return + elif not s and len(cand) == 4: + res.append('.'.join(cand)) + else: + k = min(3, len(s)) # Ensures s[:j + 1] won't be duplicate + for j in range(k): + b = s[:j + 1] + if self.is_valid_byte(b): + cand.append(b) + self.restore_ip(s[j + 1:], cand, res) + cand.pop() + + def is_valid_byte(self, b): + if b == '0': + return True + elif b.startswith('0'): + return False + else: + return int(b) < 256 + +a = "25525511135" +b = "010010" +s = Solution() +print(s.restoreIpAddresses(a)) +print(s.restoreIpAddresses(b)) From b17242c80e209e5bc3c0e7d5b6937f4050d287d4 Mon Sep 17 00:00:00 2001 From: Shichao An Date: Thu, 20 Aug 2015 17:57:16 -0700 Subject: [PATCH 05/35] Added more problems --- climbing_stairs/solution.py | 17 ++++++++++++++ climbing_stairs/solution2.py | 8 +++++++ count_primes/solution.py | 37 +++++++++++++++++++++++++++++ count_primes/solution2.py | 34 +++++++++++++++++++++++++++ house_robber/solution.py | 34 +++++++++++++++++++++++++++ majority_element/solution.py | 24 +++++++++++++++++++ summary_ranges/solution.py | 45 ++++++++++++++++++++++++++++++++++++ 7 files changed, 199 insertions(+) create mode 100644 count_primes/solution.py create mode 100644 count_primes/solution2.py create mode 100644 house_robber/solution.py create mode 100644 majority_element/solution.py create mode 100644 summary_ranges/solution.py diff --git a/climbing_stairs/solution.py b/climbing_stairs/solution.py index fb8e9a3..1bb0938 100644 --- a/climbing_stairs/solution.py +++ b/climbing_stairs/solution.py @@ -1,7 +1,16 @@ +""" +You are climbing a stair case. It takes n steps to reach to the top. + +Each time you can either climb 1 or 2 steps. In how many distinct ways can you +climb to the top? +""" + class Solution: # @param n, an integer # @return an integer def climbStairs(self, n): + if n == 0: + return 1 t = [0] * (n + 1) t[1] = 1 if n == 1: @@ -12,3 +21,11 @@ def climbStairs(self, n): for i in range(3, n + 1): t[i] = t[i - 1] + t[i - 2] return t[n] + + +s = Solution() +print(s.climbStairs(0)) +print(s.climbStairs(1)) +print(s.climbStairs(2)) +print(s.climbStairs(3)) +print(s.climbStairs(4)) diff --git a/climbing_stairs/solution2.py b/climbing_stairs/solution2.py index 1eafd24..0683a79 100644 --- a/climbing_stairs/solution2.py +++ b/climbing_stairs/solution2.py @@ -15,3 +15,11 @@ def climb(self, n, t): else: t[n] = self.climb(n - 1, t) + self.climb(n - 2, t) return t[n] + + +s = Solution() +print(s.climbStairs(0)) +print(s.climbStairs(1)) +print(s.climbStairs(2)) +print(s.climbStairs(3)) +print(s.climbStairs(4)) diff --git a/count_primes/solution.py b/count_primes/solution.py new file mode 100644 index 0000000..6f4a7d4 --- /dev/null +++ b/count_primes/solution.py @@ -0,0 +1,37 @@ +""" +Description: + +Count the number of prime numbers less than a non-negative number, n. + +Hint: + +Let's start with a isPrime function. To determine if a number is prime, we +need to check if it is not divisible by any number less than n. The runtime +complexity of isPrime function would be O(n) and hence counting the total +prime numbers up to n would be O(n2). Could we do better? + +""" + +class Solution(object): + def countPrimes(self, n): + """ + :type n: int + :rtype: int + """ + res = 0 + for i in range(2, n): + if self.is_prime(i): + res += 1 + return res + + def is_prime(self, k): + i = 2 + while i * i <= k: + if k % i == 0: + return False + i += 1 + return True + + +s = Solution() +print(s.countPrimes(500)) diff --git a/count_primes/solution2.py b/count_primes/solution2.py new file mode 100644 index 0000000..c7b0226 --- /dev/null +++ b/count_primes/solution2.py @@ -0,0 +1,34 @@ +""" +Description: + +Count the number of prime numbers less than a non-negative number, n. + + +""" + +class Solution(object): + def countPrimes(self, n): + """ + :type n: int + :rtype: int + """ + t = [True for i in range(n)] + i = 2 + while i * i < n: + if t[i] is False: + i += 1 + continue + j = i * i + while j < n: + t[j] = False + j += i + i += 1 + res = 0 + for i in range(2, n): + if t[i] is True: + res += 1 + return res + + +s = Solution() +print(s.countPrimes(500)) diff --git a/house_robber/solution.py b/house_robber/solution.py new file mode 100644 index 0000000..14c800e --- /dev/null +++ b/house_robber/solution.py @@ -0,0 +1,34 @@ +""" +You are a professional robber planning to rob houses along a street. Each +house has a certain amount of money stashed, the only constraint stopping you +from robbing each of them is that adjacent houses have security system +connected and it will automatically contact the police if two adjacent houses +were broken into on the same night. + +Given a list of non-negative integers representing the amount of money of each +house, determine the maximum amount of money you can rob tonight without +alerting the police. +""" + +class Solution(object): + def rob(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + n = len(nums) + t = [0 for i in range(n + 1)] + if n == 0: + return t[n] + t[1] = nums[0] + if n <= 1: + return t[n] + t[2] = max(nums[:2]) + for i in range(3, n + 1): + t[i] = max(t[i - 2] + nums[i - 1], t[i - 1]) + return t[n] + + +a1 = [4, 1, 6, 10, 5, 13, 2, 7] +s = Solution() +print(s.rob(a1)) diff --git a/majority_element/solution.py b/majority_element/solution.py new file mode 100644 index 0000000..affffc3 --- /dev/null +++ b/majority_element/solution.py @@ -0,0 +1,24 @@ +""" +Given an array of size n, find the majority element. The majority element is +the element that appears more than ⌊ n/2 ⌋ times. + +You may assume that the array is non-empty and the majority element always +exist in the array. +""" + +class Solution(object): + def majorityElement(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + m = len(nums) / 2 + d = {} + for k in nums: + if k not in d: + d[k] = 1 + else: + d[k] += 1 + for k in d: + if d[k] > m: + return k diff --git a/summary_ranges/solution.py b/summary_ranges/solution.py new file mode 100644 index 0000000..0cbeadb --- /dev/null +++ b/summary_ranges/solution.py @@ -0,0 +1,45 @@ +""" +Given a sorted integer array without duplicates, return the summary of its +ranges. + +For example, given [0,1,2,4,5,7], return ["0->2","4->5","7"]. +""" + +class Solution(object): + def summaryRanges(self, nums): + """ + :type nums: List[int] + :rtype: List[str] + """ + res = [] + n = len(nums) + start = -1 + end = -1 + for i, e in enumerate(nums): + if i == 0: + start = 0 + end = 0 + else: + if e != nums[i - 1] + 1: + r = self.make_range(start, end, nums) + res.append(r) + start = i + end = i + if i == n - 1: + end = i + r = self.make_range(start, end, nums) + res.append(r) + return res + + def make_range(self, start, end, nums): + if end > start: + return "%d->%d" % (nums[start], nums[end]) + elif end == start: + return "%d" % nums[end] + + +a1 = [0, 1, 2, 4, 5, 7] +a2 = [0, 5, 9] +s = Solution() +print(s.summaryRanges(a1)) +print(s.summaryRanges(a2)) From 493f1c693dad79448cbe93ca36c90ea196eb4e18 Mon Sep 17 00:00:00 2001 From: Shichao An Date: Sat, 22 Aug 2015 02:00:51 -0700 Subject: [PATCH 06/35] Added course schedule: BFS and DFS --- course_schedule/solution.py | 60 +++++++++++++++++++++++++++++++++ course_schedule/solution2.py | 65 ++++++++++++++++++++++++++++++++++++ course_schedule/test.txt | 1 + 3 files changed, 126 insertions(+) create mode 100644 course_schedule/solution.py create mode 100644 course_schedule/solution2.py create mode 100644 course_schedule/test.txt diff --git a/course_schedule/solution.py b/course_schedule/solution.py new file mode 100644 index 0000000..7bc89f8 --- /dev/null +++ b/course_schedule/solution.py @@ -0,0 +1,60 @@ +""" +There are a total of n courses you have to take, labeled from 0 to n - 1. + +Some courses may have prerequisites, for example to take course 0 you have to +first take course 1, which is expressed as a pair: [0,1] + +Given the total number of courses and a list of prerequisite pairs, is it +possible for you to finish all courses? + +For example: + +2, [[1,0]] +There are a total of 2 courses to take. To take course 1 you should have +finished course 0. So it is possible. + +2, [[1,0],[0,1]] +There are a total of 2 courses to take. To take course 1 you should have +finished course 0, and to take course 0 you should also have finished course +1. So it is impossible. +""" + +class Solution(object): + def canFinish(self, numCourses, prerequisites): + """ + :type numCourses: int + :type prerequisites: List[List[int]] + :rtype: bool + """ + # An implementation of + # https://en.wikipedia.org/wiki/Topological_sorting#Algorithms + # + # Graph in which each node has its prerequisite courses as a + # adjacency list + queue = [] + finished_courses = [] + prq_graph = {x: set() for x in range(numCourses)} + for c, p in prerequisites: + prq_graph[c].add(p) + + # Add nodes with no prerequisites + for c in prq_graph: + if not prq_graph[c]: + queue.append(c) + + # For each of the remaining node, remove its prerequisites in queue; + # if node has no prerequisites, add it to queue, and repeat + while queue: + u = queue.pop(0) + for v, prqs in prq_graph.items(): + if u in prqs: + prqs.remove(u) + if not prqs: + queue.append(v) + finished_courses.append(u) + + return len(finished_courses) == numCourses + +s = Solution() +print(s.canFinish(1, [])) +print(s.canFinish(3, [[1, 0], [0, 1]])) diff --git a/course_schedule/solution2.py b/course_schedule/solution2.py new file mode 100644 index 0000000..bcd9edc --- /dev/null +++ b/course_schedule/solution2.py @@ -0,0 +1,65 @@ +""" +There are a total of n courses you have to take, labeled from 0 to n - 1. + +Some courses may have prerequisites, for example to take course 0 you have to +first take course 1, which is expressed as a pair: [0,1] + +Given the total number of courses and a list of prerequisite pairs, is it +possible for you to finish all courses? + +For example: + +2, [[1,0]] +There are a total of 2 courses to take. To take course 1 you should have +finished course 0. So it is possible. + +2, [[1,0],[0,1]] +There are a total of 2 courses to take. To take course 1 you should have +finished course 0, and to take course 0 you should also have finished course +1. So it is impossible. +""" +import sys + +sys.setrecursionlimit(5000) + +class Solution(object): + def canFinish(self, numCourses, prerequisites): + """ + :type numCourses: int + :type prerequisites: List[List[int]] + :rtype: bool + """ + + self.unvisited = set(range(numCourses)) + self.visiting = set() + self.visited = set() + self.graph = {x: set() for x in range(numCourses)} + for c, p in prerequisites: + self.graph[p].add(c) + + for u in range(numCourses): + if u in self.unvisited: + if self.visit(u) is False: + return False + return True + + def visit(self, u): + if u in self.visiting: + return False + elif u in self.unvisited: + self.unvisited.remove(u) + self.visiting.add(u) + for v in self.graph[u]: + if self.visit(v) is False: + return False + self.visiting.remove(u) + self.visited.add(u) + +s = Solution() +print(s.canFinish(1, [])) +print(s.canFinish(3, [[1, 0], [0, 1]])) +with open('test.txt') as f: + args = f.read().split() + arg0 = int(args[0][:-1]) + arg1 = eval(args[1]) + print(s.canFinish(arg0, arg1)) diff --git a/course_schedule/test.txt b/course_schedule/test.txt new file mode 100644 index 0000000..c6a9f33 --- /dev/null +++ b/course_schedule/test.txt @@ -0,0 +1 @@ +2000, [[781,650],[650,1175],[1175,1961],[1961,1414],[1414,1144],[1144,461],[461,1450],[1450,1836],[1836,754],[754,1429],[1429,97],[97,385],[385,1260],[1260,1345],[1345,1751],[1751,1775],[1775,1273],[1273,18],[18,1307],[1307,859],[859,1792],[1792,1258],[1258,1609],[1609,999],[999,1485],[1485,887],[887,82],[82,285],[285,1026],[1026,1442],[1442,328],[328,224],[224,33],[33,1687],[1687,1797],[1797,510],[510,1266],[1266,1984],[1984,314],[314,1314],[1314,67],[67,375],[375,1969],[1969,560],[560,1466],[1466,1362],[1362,1672],[1672,1657],[1657,1323],[1323,114],[114,745],[745,1455],[1455,1306],[1306,241],[241,960],[960,271],[271,57],[57,324],[324,400],[400,609],[609,721],[721,1387],[1387,793],[793,482],[482,873],[873,311],[311,833],[833,637],[637,491],[491,886],[886,1426],[1426,201],[201,1740],[1740,183],[183,1706],[1706,626],[626,546],[546,318],[318,903],[903,1979],[1979,69],[69,472],[472,16],[16,576],[576,1370],[1370,1691],[1691,665],[665,256],[256,1884],[1884,548],[548,28],[28,176],[176,252],[252,1105],[1105,274],[274,1721],[1721,1718],[1718,906],[906,852],[852,1435],[1435,865],[865,896],[896,699],[699,1156],[1156,259],[259,1399],[1399,740],[740,673],[673,622],[622,984],[984,794],[794,963],[963,1753],[1753,1454],[1454,1017],[1017,1636],[1636,627],[627,1498],[1498,1628],[1628,628],[628,513],[513,1044],[1044,1564],[1564,933],[933,653],[653,1401],[1401,909],[909,1768],[1768,840],[840,1749],[1749,554],[554,1326],[1326,1931],[1931,844],[844,645],[645,1592],[1592,1183],[1183,306],[306,1949],[1949,1970],[1970,1680],[1680,27],[27,1329],[1329,277],[277,354],[354,612],[612,1844],[1844,1389],[1389,550],[550,1291],[1291,1524],[1524,686],[686,688],[688,1845],[1845,448],[448,730],[730,1603],[1603,185],[185,109],[109,591],[591,1159],[1159,1919],[1919,380],[380,719],[719,728],[728,1873],[1873,1093],[1093,969],[969,1798],[1798,1413],[1413,492],[492,365],[365,1988],[1988,695],[695,14],[14,773],[773,177],[177,1720],[1720,1964],[1964,1432],[1432,1187],[1187,1479],[1479,784],[784,118],[118,741],[741,967],[967,1641],[1641,490],[490,966],[966,1591],[1591,1778],[1778,1576],[1576,1615],[1615,723],[723,1724],[1724,1954],[1954,1709],[1709,96],[96,1486],[1486,1642],[1642,1776],[1776,994],[994,1758],[1758,1983],[1983,483],[483,917],[917,738],[738,1428],[1428,1852],[1852,1648],[1648,1953],[1953,155],[155,181],[181,815],[815,1180],[1180,1666],[1666,88],[88,1226],[1226,876],[876,1179],[1179,251],[251,720],[720,1073],[1073,1042],[1042,1599],[1599,102],[102,372],[372,466],[466,636],[636,1892],[1892,620],[620,164],[164,866],[866,1646],[1646,1253],[1253,467],[467,1342],[1342,1584],[1584,540],[540,1104],[1104,543],[543,1677],[1677,529],[529,1705],[1705,429],[429,1606],[1606,1202],[1202,1886],[1886,508],[508,883],[883,694],[694,1542],[1542,1774],[1774,371],[371,1586],[1586,414],[414,1877],[1877,1398],[1398,1182],[1182,644],[644,809],[809,890],[890,1035],[1035,390],[390,1671],[1671,970],[970,756],[756,1267],[1267,1332],[1332,158],[158,1587],[1587,1940],[1940,475],[475,478],[478,1206],[1206,590],[590,1731],[1731,573],[573,392],[392,1728],[1728,281],[281,1834],[1834,404],[404,1471],[1471,615],[615,1109],[1109,621],[621,1861],[1861,925],[925,1874],[1874,1882],[1882,1013],[1013,1367],[1367,1660],[1660,1380],[1380,243],[243,722],[722,668],[668,1526],[1526,1855],[1855,1118],[1118,1243],[1243,128],[128,1842],[1842,1178],[1178,1472],[1472,370],[370,1437],[1437,1274],[1274,434],[434,1782],[1782,511],[511,402],[402,1982],[1982,1875],[1875,703],[703,1131],[1131,1085],[1085,1034],[1034,1181],[1181,1467],[1467,556],[556,139],[139,298],[298,1440],[1440,1298],[1298,1899],[1899,1978],[1978,1217],[1217,1951],[1951,1683],[1683,1280],[1280,1204],[1204,405],[405,99],[99,1448],[1448,162],[162,1112],[1112,1157],[1157,1929],[1929,1890],[1890,1926],[1926,1302],[1302,1425],[1425,1699],[1699,565],[565,1627],[1627,1483],[1483,1676],[1676,66],[66,1116],[1116,986],[986,1041],[1041,62],[62,1818],[1818,1888],[1888,355],[355,266],[266,431],[431,1218],[1218,1763],[1763,115],[115,997],[997,1099],[1099,936],[936,249],[249,1704],[1704,930],[930,1560],[1560,1230],[1230,646],[646,144],[144,1059],[1059,1506],[1506,791],[791,811],[811,1427],[1427,595],[595,413],[413,1800],[1800,399],[399,299],[299,1902],[1902,1679],[1679,1871],[1871,87],[87,1914],[1914,260],[260,361],[361,1726],[1726,1880],[1880,200],[200,1225],[1225,1772],[1772,1608],[1608,1866],[1866,1346],[1346,538],[538,669],[669,1000],[1000,1190],[1190,330],[330,1434],[1434,1896],[1896,117],[117,1779],[1779,836],[836,1692],[1692,1386],[1386,417],[417,596],[596,1993],[1993,422],[422,1248],[1248,928],[928,253],[253,1012],[1012,457],[457,1991],[1991,1412],[1412,1801],[1801,1127],[1127,1331],[1331,1920],[1920,1945],[1945,671],[671,1837],[1837,317],[317,301],[301,335],[335,1674],[1674,1121],[1121,1921],[1921,1198],[1198,411],[411,1152],[1152,1277],[1277,1912],[1912,586],[586,310],[310,1525],[1525,1174],[1174,1254],[1254,284],[284,1103],[1103,1350],[1350,1396],[1396,835],[835,1509],[1509,1275],[1275,127],[127,206],[206,188],[188,1960],[1960,980],[980,1122],[1122,77],[77,31],[31,652],[652,1507],[1507,386],[386,655],[655,129],[129,1215],[1215,1552],[1552,1620],[1620,1616],[1616,696],[696,1223],[1223,1719],[1719,1548],[1548,455],[455,920],[920,1601],[1601,1421],[1421,509],[509,257],[257,1007],[1007,680],[680,675],[675,240],[240,1682],[1682,661],[661,484],[484,327],[327,132],[132,1518],[1518,1827],[1827,687],[687,195],[195,1027],[1027,469],[469,752],[752,566],[566,280],[280,796],[796,104],[104,142],[142,750],[750,957],[957,425],[425,1272],[1272,239],[239,1446],[1446,1208],[1208,888],[888,1585],[1585,1655],[1655,391],[391,1905],[1905,1697],[1697,972],[972,1166],[1166,101],[101,65],[65,727],[727,797],[797,1795],[1795,1972],[1972,1808],[1808,558],[558,1745],[1745,1813],[1813,296],[296,826],[826,1901],[1901,12],[12,683],[683,1110],[1110,1312],[1312,1725],[1725,685],[685,691],[691,407],[407,1147],[1147,1809],[1809,1965],[1965,332],[332,1785],[1785,393],[393,639],[639,998],[998,976],[976,1381],[1381,1349],[1349,1402],[1402,60],[60,154],[154,93],[93,1784],[1784,1384],[1384,351],[351,1959],[1959,1826],[1826,855],[855,843],[843,1072],[1072,1865],[1865,1805],[1805,1231],[1231,1600],[1600,1517],[1517,394],[394,850],[850,1742],[1742,789],[789,442],[442,4],[4,169],[169,838],[838,631],[631,915],[915,932],[932,604],[604,1997],[1997,1995],[1995,230],[230,1799],[1799,309],[309,1209],[1209,1541],[1541,707],[707,90],[90,1288],[1288,1487],[1487,885],[885,146],[146,1256],[1256,137],[137,901],[901,520],[520,746],[746,148],[148,1911],[1911,1673],[1673,772],[772,597],[597,856],[856,61],[61,1503],[1503,507],[507,1568],[1568,288],[288,40],[40,996],[996,401],[401,1461],[1461,1464],[1464,46],[46,1240],[1240,20],[20,1743],[1743,1065],[1065,1056],[1056,79],[79,1579],[1579,1261],[1261,44],[44,767],[767,1932],[1932,292],[292,373],[373,1734],[1734,1968],[1968,1385],[1385,1501],[1501,321],[321,1605],[1605,350],[350,1786],[1786,598],[598,803],[803,1018],[1018,198],[198,757],[757,486],[486,468],[468,893],[893,924],[924,1573],[1573,126],[126,783],[783,1299],[1299,1358],[1358,26],[26,1263],[1263,758],[758,1014],[1014,927],[927,130],[130,729],[729,473],[473,1321],[1321,202],[202,210],[210,1693],[1693,657],[657,1259],[1259,1430],[1430,1328],[1328,1108],[1108,534],[534,1863],[1863,555],[555,1347],[1347,1392],[1392,1575],[1575,710],[710,654],[654,1079],[1079,1224],[1224,171],[171,1251],[1251,1352],[1352,1141],[1141,945],[945,1058],[1058,1172],[1172,1746],[1746,449],[449,1610],[1610,493],[493,1955],[1955,503],[503,450],[450,1717],[1717,1950],[1950,1638],[1638,1069],[1069,419],[419,170],[170,816],[816,152],[152,362],[362,1958],[1958,1005],[1005,813],[813,1213],[1213,956],[956,1216],[1216,1747],[1747,1153],[1153,1815],[1815,1031],[1031,1074],[1074,428],[428,625],[625,708],[708,1364],[1364,1102],[1102,857],[857,795],[795,1824],[1824,1935],[1935,1284],[1284,1419],[1419,717],[717,1094],[1094,23],[23,81],[81,1310],[1310,1624],[1624,701],[701,131],[131,541],[541,1702],[1702,1545],[1545,1322],[1322,270],[270,49],[49,742],[742,1145],[1145,726],[726,1372],[1372,1476],[1476,1249],[1249,1228],[1228,1810],[1810,1571],[1571,1986],[1986,1851],[1851,1171],[1171,1802],[1802,1028],[1028,1030],[1030,1126],[1126,1054],[1054,1091],[1091,278],[278,762],[762,824],[824,1481],[1481,1378],[1378,136],[136,755],[755,764],[764,216],[216,905],[905,1977],[1977,982],[982,1055],[1055,1357],[1357,1265],[1265,1546],[1546,1872],[1872,379],[379,1701],[1701,398],[398,1645],[1645,437],[437,1535],[1535,1904],[1904,78],[78,1612],[1612,1668],[1668,245],[245,849],[849,83],[83,954],[954,1558],[1558,1494],[1494,1239],[1239,964],[964,825],[825,1375],[1375,821],[821,68],[68,1443],[1443,869],[869,123],[123,470],[470,1647],[1647,1513],[1513,329],[329,1004],[1004,800],[800,517],[517,34],[34,423],[423,634],[634,562],[562,273],[273,1770],[1770,1316],[1316,713],[713,978],[978,315],[315,1678],[1678,1848],[1848,1077],[1077,1536],[1536,500],[500,662],[662,1910],[1910,147],[147,585],[585,777],[777,235],[235,421],[421,1733],[1733,22],[22,1214],[1214,1344],[1344,297],[297,1803],[1803,1849],[1849,874],[874,1879],[1879,934],[934,955],[955,831],[831,348],[348,1057],[1057,1011],[1011,1024],[1024,219],[219,1097],[1097,539],[539,870],[870,1351],[1351,810],[810,363],[363,487],[487,218],[218,454],[454,1956],[1956,1651],[1651,841],[841,480],[480,262],[262,1893],[1893,1941],[1941,1359],[1359,356],[356,347],[347,1083],[1083,1821],[1821,1478],[1478,180],[180,247],[247,333],[333,1468],[1468,771],[771,931],[931,1830],[1830,1390],[1390,232],[232,1080],[1080,322],[322,537],[537,1822],[1822,1595],[1595,666],[666,1823],[1823,248],[248,1368],[1368,1741],[1741,3],[3,1451],[1451,618],[618,1626],[1626,718],[718,939],[939,184],[184,1337],[1337,806],[806,1029],[1029,374],[374,11],[11,189],[189,947],[947,1066],[1066,1046],[1046,640],[640,124],[124,1976],[1976,420],[420,462],[462,670],[670,1037],[1037,456],[456,276],[276,89],[89,904],[904,140],[140,1895],[1895,1395],[1395,1563],[1563,1191],[1191,246],[246,1459],[1459,851],[851,1439],[1439,1766],[1766,92],[92,1582],[1582,1520],[1520,705],[705,54],[54,884],[884,743],[743,1832],[1832,1710],[1710,410],[410,1916],[1916,1045],[1045,1010],[1010,443],[443,15],[15,1247],[1247,1788],[1788,55],[55,549],[549,1232],[1232,1416],[1416,225],[225,8],[8,1529],[1529,1148],[1148,353],[353,1860],[1860,376],[376,531],[531,339],[339,418],[418,250],[250,733],[733,325],[325,258],[258,599],[599,951],[951,1730],[1730,959],[959,1658],[1658,331],[331,571],[571,1319],[1319,1762],[1762,551],[551,269],[269,1363],[1363,261],[261,121],[121,837],[837,842],[842,961],[961,1688],[1688,808],[808,1137],[1137,1143],[1143,220],[220,1990],[1990,1760],[1760,760],[760,1114],[1114,1164],[1164,1493],[1493,921],[921,1870],[1870,496],[496,731],[731,1767],[1767,1759],[1759,1499],[1499,1068],[1068,697],[697,914],[914,1169],[1169,1296],[1296,190],[190,1405],[1405,474],[474,435],[435,192],[192,149],[149,412],[412,1151],[1151,494],[494,1379],[1379,1020],[1020,1295],[1295,1233],[1233,608],[608,145],[145,74],[74,1246],[1246,846],[846,438],[438,263],[263,1167],[1167,1534],[1534,895],[895,1820],[1820,1282],[1282,1936],[1936,582],[582,1474],[1474,1285],[1285,396],[396,120],[120,698],[698,1407],[1407,1071],[1071,593],[593,944],[944,1197],[1197,1947],[1947,1161],[1161,938],[938,1796],[1796,340],[340,1470],[1470,971],[971,1376],[1376,1989],[1989,1107],[1107,1092],[1092,197],[197,1039],[1039,1480],[1480,215],[215,1445],[1445,1052],[1052,1420],[1420,1739],[1739,525],[525,1854],[1854,1257],[1257,937],[937,165],[165,1033],[1033,1212],[1212,568],[568,763],[763,313],[313,1681],[1681,1653],[1653,1637],[1637,207],[207,1264],[1264,953],[953,1580],[1580,415],[415,388],[388,110],[110,168],[168,1562],[1562,1944],[1944,822],[822,897],[897,1447],[1447,1355],[1355,871],[871,1812],[1812,1075],[1075,1076],[1076,161],[161,656],[656,1356],[1356,1294],[1294,203],[203,10],[10,383],[383,236],[236,1100],[1100,1317],[1317,294],[294,1348],[1348,1089],[1089,302],[302,209],[209,1279],[1279,1369],[1369,572],[572,1095],[1095,1975],[1975,64],[64,95],[95,1814],[1814,725],[725,1611],[1611,1783],[1783,1130],[1130,1334],[1334,1639],[1639,275],[275,759],[759,463],[463,689],[689,227],[227,1806],[1806,1971],[1971,975],[975,1828],[1828,1557],[1557,1889],[1889,1188],[1188,501],[501,1406],[1406,291],[291,968],[968,366],[366,1003],[1003,1135],[1135,1623],[1623,589],[589,488],[488,1366],[1366,1781],[1781,51],[51,610],[610,526],[526,135],[135,747],[747,1962],[1962,1192],[1192,312],[312,1134],[1134,349],[349,912],[912,732],[732,1908],[1908,1394],[1394,1723],[1723,820],[820,616],[616,926],[926,1773],[1773,624],[624,868],[868,660],[660,563],[563,1942],[1942,1883],[1883,319],[319,1619],[1619,39],[39,1465],[1465,962],[962,1160],[1160,606],[606,406],[406,1839],[1839,711],[711,58],[58,1021],[1021,775],[775,1339],[1339,38],[38,231],[231,1925],[1925,119],[119,1881],[1881,1829],[1829,532],[532,1128],[1128,561],[561,41],[41,533],[533,1735],[1735,802],[802,32],[32,858],[858,1640],[1640,459],[459,1907],[1907,1318],[1318,875],[875,1195],[1195,545],[545,1566],[1566,1514],[1514,958],[958,1484],[1484,1550],[1550,1196],[1196,1869],[1869,35],[35,228],[228,217],[217,950],[950,1165],[1165,1594],[1594,502],[502,444],[444,1900],[1900,337],[337,1088],[1088,635],[635,84],[84,1974],[1974,471],[471,94],[94,676],[676,178],[178,1793],[1793,48],[48,73],[73,1409],[1409,1523],[1523,734],[734,191],[191,382],[382,577],[577,642],[642,899],[899,1186],[1186,1711],[1711,965],[965,56],[56,1670],[1670,1868],[1868,580],[580,268],[268,436],[436,1001],[1001,212],[212,1238],[1238,514],[514,1185],[1185,1857],[1857,1732],[1732,1897],[1897,432],[432,1096],[1096,1393],[1393,1597],[1597,516],[516,1664],[1664,163],[163,1305],[1305,326],[326,748],[748,1549],[1549,922],[922,1937],[1937,1635],[1635,787],[787,575],[575,1244],[1244,693],[693,735],[735,369],[369,1533],[1533,427],[427,1111],[1111,892],[892,1512],[1512,681],[681,774],[774,1570],[1570,807],[807,141],[141,1700],[1700,1939],[1939,1755],[1755,17],[17,1938],[1938,1200],[1200,1761],[1761,1722],[1722,1168],[1168,1098],[1098,780],[780,714],[714,1604],[1604,343],[343,1631],[1631,433],[433,1449],[1449,293],[293,515],[515,1572],[1572,103],[103,1790],[1790,408],[408,1819],[1819,1287],[1287,860],[860,557],[557,910],[910,105],[105,283],[283,1583],[1583,174],[174,559],[559,1155],[1155,804],[804,611],[611,1923],[1923,1173],[1173,613],[613,761],[761,1853],[1853,913],[913,1113],[1113,1738],[1738,766],[766,194],[194,1675],[1675,1876],[1876,1696],[1696,649],[649,829],[829,583],[583,946],[946,1515],[1515,658],[658,1227],[1227,1124],[1124,1453],[1453,416],[416,1544],[1544,667],[667,1555],[1555,1522],[1522,736],[736,1132],[1132,1538],[1538,290],[290,1933],[1933,1343],[1343,1490],[1490,864],[864,1150],[1150,221],[221,853],[853,264],[264,607],[607,1106],[1106,1325],[1325,700],[700,1120],[1120,1613],[1613,1521],[1521,122],[122,1189],[1189,175],[175,205],[205,1360],[1360,1708],[1708,1617],[1617,1750],[1750,1530],[1530,113],[113,854],[854,1707],[1707,504],[504,1162],[1162,907],[907,24],[24,481],[481,902],[902,1374],[1374,588],[588,587],[587,877],[877,1577],[1577,682],[682,1505],[1505,564],[564,630],[630,439],[439,1043],[1043,702],[702,1569],[1569,1553],[1553,527],[527,138],[138,1777],[1777,1694],[1694,724],[724,569],[569,1841],[1841,812],[812,574],[574,1744],[1744,1492],[1492,1669],[1669,1327],[1327,1308],[1308,1237],[1237,769],[769,304],[304,1444],[1444,1115],[1115,242],[242,1062],[1062,948],[948,1353],[1353,1270],[1270,1622],[1622,552],[552,1496],[1496,1748],[1748,159],[159,542],[542,739],[739,1025],[1025,1510],[1510,1400],[1400,1408],[1408,1867],[1867,991],[991,830],[830,1008],[1008,715],[715,553],[553,1320],[1320,1729],[1729,1262],[1262,1061],[1061,182],[182,1654],[1654,238],[238,1154],[1154,709],[709,1686],[1686,663],[663,633],[633,1462],[1462,1593],[1593,579],[579,1690],[1690,987],[987,267],[267,614],[614,1999],[1999,1365],[1365,91],[91,1927],[1927,1002],[1002,479],[479,1987],[1987,768],[768,153],[153,993],[993,156],[156,1438],[1438,1081],[1081,1596],[1596,30],[30,1913],[1913,497],[497,1],[1,1539],[1539,1219],[1219,845],[845,338],[338,1885],[1885,387],[387,1023],[1023,744],[744,1630],[1630,106],[106,1292],[1292,286],[286,1915],[1915,919],[919,45],[45,889],[889,706],[706,1255],[1255,506],[506,1831],[1831,1661],[1661,1221],[1221,166],[166,1194],[1194,952],[952,677],[677,1847],[1847,1423],[1423,1397],[1397,76],[76,303],[303,1946],[1946,1229],[1229,799],[799,1527],[1527,451],[451,1887],[1887,287],[287,523],[523,1441],[1441,1060],[1060,1698],[1698,1540],[1540,476],[476,13],[13,578],[578,1737],[1737,211],[211,229],[229,1241],[1241,1417],[1417,839],[839,1771],[1771,1765],[1765,1313],[1313,1422],[1422,818],[818,1607],[1607,623],[623,1431],[1431,112],[112,1036],[1036,1878],[1878,237],[237,1543],[1543,1482],[1482,908],[908,307],[307,368],[368,1146],[1146,834],[834,1504],[1504,1268],[1268,521],[521,1650],[1650,819],[819,651],[651,1551],[1551,0],[0,133],[133,1567],[1567,1304],[1304,1994],[1994,765],[765,1090],[1090,308],[308,222],[222,1966],[1966,2],[2,1290],[1290,678],[678,1477],[1477,1193],[1193,1754],[1754,1403],[1403,1163],[1163,1922],[1922,1210],[1210,530],[530,1032],[1032,1391],[1391,1278],[1278,1588],[1588,316],[316,1667],[1667,300],[300,395],[395,63],[63,918],[918,47],[47,272],[272,495],[495,848],[848,1663],[1663,1727],[1727,601],[601,1361],[1361,498],[498,1574],[1574,941],[941,1757],[1757,1457],[1457,1040],[1040,485],[485,878],[878,1864],[1864,323],[323,1201],[1201,1811],[1811,1473],[1473,1621],[1621,1858],[1858,1078],[1078,1335],[1335,684],[684,1756],[1756,367],[367,1303],[1303,1590],[1590,1764],[1764,524],[524,426],[426,1415],[1415,1340],[1340,1082],[1082,916],[916,1176],[1176,1311],[1311,1614],[1614,751],[751,1333],[1333,1906],[1906,1684],[1684,1377],[1377,477],[477,1589],[1589,85],[85,1125],[1125,157],[157,1140],[1140,1315],[1315,1338],[1338,359],[359,1136],[1136,244],[244,1158],[1158,150],[150,1411],[1411,1245],[1245,1371],[1371,1250],[1250,1794],[1794,847],[847,1502],[1502,381],[381,42],[42,295],[295,632],[632,1963],[1963,1475],[1475,692],[692,1336],[1336,1006],[1006,25],[25,770],[770,567],[567,704],[704,345],[345,254],[254,1211],[1211,160],[160,995],[995,397],[397,992],[992,1980],[1980,187],[187,1086],[1086,801],[801,1271],[1271,1047],[1047,1511],[1511,1843],[1843,792],[792,1038],[1038,464],[464,59],[59,1769],[1769,643],[643,753],[753,52],[52,1957],[1957,974],[974,1662],[1662,1497],[1497,1559],[1559,75],[75,1424],[1424,70],[70,80],[80,430],[430,208],[208,1460],[1460,584],[584,346],[346,358],[358,1301],[1301,629],[629,1404],[1404,1625],[1625,894],[894,776],[776,378],[378,1602],[1602,1410],[1410,282],[282,21],[21,6],[6,1207],[1207,458],[458,409],[409,1632],[1632,1500],[1500,1659],[1659,1495],[1495,779],[779,377],[377,179],[179,1050],[1050,1714],[1714,364],[364,1469],[1469,881],[881,424],[424,489],[489,389],[389,1203],[1203,213],[213,641],[641,143],[143,1433],[1433,1488],[1488,535],[535,1452],[1452,167],[167,226],[226,1652],[1652,647],[647,460],[460,499],[499,872],[872,1133],[1133,1064],[1064,1516],[1516,1791],[1791,882],[882,452],[452,53],[53,778],[778,1184],[1184,547],[547,505],[505,900],[900,1943],[1943,125],[125,1780],[1780,1894],[1894,1634],[1634,1324],[1324,679],[679,1856],[1856,1649],[1649,863],[863,536],[536,1051],[1051,107],[107,1300],[1300,1531],[1531,204],[204,1289],[1289,37],[37,1547],[1547,43],[43,1491],[1491,223],[223,1063],[1063,929],[929,1934],[1934,522],[522,600],[600,172],[172,544],[544,1928],[1928,71],[71,1170],[1170,1629],[1629,1236],[1236,279],[279,1918],[1918,1101],[1101,1016],[1016,749],[749,1862],[1862,602],[602,827],[827,1685],[1685,342],[342,1787],[1787,672],[672,985],[985,1456],[1456,664],[664,1598],[1598,1850],[1850,1924],[1924,352],[352,1199],[1199,1252],[1252,1436],[1436,1656],[1656,1807],[1807,942],[942,619],[619,116],[116,1985],[1985,1556],[1556,1581],[1581,879],[879,981],[981,186],[186,570],[570,737],[737,1528],[1528,786],[786,1070],[1070,234],[234,440],[440,1293],[1293,1117],[1117,193],[193,1220],[1220,1129],[1129,1418],[1418,1618],[1618,384],[384,1269],[1269,108],[108,1833],[1833,199],[199,233],[233,19],[19,360],[360,798],[798,214],[214,465],[465,5],[5,9],[9,1840],[1840,1388],[1388,690],[690,817],[817,1508],[1508,1142],[1142,403],[403,1903],[1903,36],[36,86],[86,898],[898,1695],[1695,1909],[1909,1891],[1891,1752],[1752,528],[528,1222],[1222,1859],[1859,1015],[1015,441],[441,949],[949,1330],[1330,716],[716,1382],[1382,1713],[1713,1463],[1463,1235],[1235,1917],[1917,1712],[1712,1458],[1458,1123],[1123,1898],[1898,289],[289,1578],[1578,1846],[1846,1789],[1789,1665],[1665,1009],[1009,990],[990,790],[790,1736],[1736,973],[973,453],[453,1177],[1177,674],[674,1537],[1537,1689],[1689,196],[196,832],[832,935],[935,940],[940,445],[445,518],[518,1139],[1139,265],[265,1973],[1973,828],[828,1967],[1967,1309],[1309,1242],[1242,1373],[1373,1554],[1554,782],[782,1565],[1565,659],[659,1149],[1149,1716],[1716,72],[72,98],[98,1276],[1276,983],[983,305],[305,867],[867,862],[862,594],[594,1948],[1948,1354],[1354,1138],[1138,447],[447,805],[805,1998],[1998,1084],[1084,603],[603,134],[134,1825],[1825,617],[617,1992],[1992,979],[979,1053],[1053,814],[814,1804],[1804,1561],[1561,1835],[1835,911],[911,1341],[1341,341],[341,1489],[1489,334],[334,712],[712,1297],[1297,1383],[1383,648],[648,50],[50,1067],[1067,1048],[1048,1633],[1633,151],[151,943],[943,1022],[1022,7],[7,1816],[1816,788],[788,861],[861,988],[988,1234],[1234,1952],[1952,1715],[1715,1283],[1283,446],[446,1703],[1703,923],[923,255],[255,1119],[1119,357],[357,1930],[1930,173],[173,1281],[1281,1644],[1644,605],[605,1019],[1019,1286],[1286,638],[638,891],[891,29],[29,519],[519,1532],[1532,1519],[1519,1087],[1087,581],[581,1981],[1981,336],[336,785],[785,1205],[1205,989],[989,1817],[1817,512],[512,592],[592,1838],[1838,977],[977,1049],[1049,320],[320,880],[880,823],[823,1643],[1643,1996],[1996,100],[100,111],[111,344],[344,781]] From f0e3ff1d8b3de11af2db6658908398ead54551e5 Mon Sep 17 00:00:00 2001 From: Shichao An Date: Sat, 22 Aug 2015 20:27:23 -0700 Subject: [PATCH 07/35] Added alternative solution --- implement_strstr/solution.py | 14 ++++++++------ implement_strstr/solution2.py | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 implement_strstr/solution2.py diff --git a/implement_strstr/solution.py b/implement_strstr/solution.py index 402923a..5be4391 100644 --- a/implement_strstr/solution.py +++ b/implement_strstr/solution.py @@ -1,8 +1,10 @@ -class Solution: - # @param haystack, a string - # @param needle, a string - # @return a string or None +class Solution(object): def strStr(self, haystack, needle): + """ + :type haystack: str + :type needle: str + :rtype: int + """ n = len(haystack) m = len(needle) for i in range(n + 1 - m): @@ -12,5 +14,5 @@ def strStr(self, haystack, needle): matched = False break if matched: - return haystack[i:] - return None + return i + return -1 diff --git a/implement_strstr/solution2.py b/implement_strstr/solution2.py new file mode 100644 index 0000000..14ed87f --- /dev/null +++ b/implement_strstr/solution2.py @@ -0,0 +1,16 @@ +class Solution(object): + def strStr(self, haystack, needle): + """ + :type haystack: str + :type needle: str + :rtype: int + """ + n = len(haystack) + m = len(needle) + for i in range(n + 1 - m): + for k in range(m): + if haystack[i + k] != needle[k]: + break + else: + return i + return -1 From 27da0c5e7003bd92c766c92505f39d7f4f3a484c Mon Sep 17 00:00:00 2001 From: Shichao An Date: Mon, 24 Aug 2015 18:42:55 -0700 Subject: [PATCH 08/35] Added more problems --- contains_duplicate/solution.py | 19 +++++++++++++ contains_duplicate_ii/solution.py | 25 +++++++++++++++++ first_missing_positive/practice.py | 0 first_missing_positive/solution.py | 10 +++++++ missing_number/solution.py | 28 +++++++++++++++++++ missing_number/solution2.py | 44 ++++++++++++++++++++++++++++++ remove_element/solution.py | 8 ++++++ 7 files changed, 134 insertions(+) create mode 100644 contains_duplicate/solution.py create mode 100644 contains_duplicate_ii/solution.py delete mode 100644 first_missing_positive/practice.py create mode 100644 missing_number/solution.py create mode 100644 missing_number/solution2.py diff --git a/contains_duplicate/solution.py b/contains_duplicate/solution.py new file mode 100644 index 0000000..eb2d02f --- /dev/null +++ b/contains_duplicate/solution.py @@ -0,0 +1,19 @@ +""" +Given an array of integers, find if the array contains any duplicates. Your +function should return true if any value appears at least twice in the array, +and it should return false if every element is distinct. +""" + +class Solution(object): + def containsDuplicate(self, nums): + """ + :type nums: List[int] + :rtype: bool + """ + d = set() + for i in nums: + if i in d: + return True + else: + d.add(i) + return False diff --git a/contains_duplicate_ii/solution.py b/contains_duplicate_ii/solution.py new file mode 100644 index 0000000..6a9a1fb --- /dev/null +++ b/contains_duplicate_ii/solution.py @@ -0,0 +1,25 @@ +""" +Given an array of integers and an integer k, find out whether there are two +distinct indices i and j in the array such that nums[i] = nums[j] and the +difference between i and j is at most k. +""" + +class Solution(object): + def containsNearbyDuplicate(self, nums, k): + """ + :type nums: List[int] + :type k: int + :rtype: bool + """ + d = {} + for i, e in enumerate(nums): + if e in d: + if i - d[e] <= k: + return True + d[e] = i + return False + + +args1 = [[1, 0, 1, 1], 1] +s = Solution() +print(s.containsNearbyDuplicate(*args1)) diff --git a/first_missing_positive/practice.py b/first_missing_positive/practice.py deleted file mode 100644 index e69de29..0000000 diff --git a/first_missing_positive/solution.py b/first_missing_positive/solution.py index 0055689..96b0b98 100644 --- a/first_missing_positive/solution.py +++ b/first_missing_positive/solution.py @@ -1,3 +1,13 @@ +""" +Given an unsorted integer array, find the first missing positive integer. + +For example, +Given [1,2,0] return 3, +and [3,4,-1,1] return 2. + +Your algorithm should run in O(n) time and uses constant space. +""" + class Solution: # @param A, a list of integers # @return an integer diff --git a/missing_number/solution.py b/missing_number/solution.py new file mode 100644 index 0000000..49ed212 --- /dev/null +++ b/missing_number/solution.py @@ -0,0 +1,28 @@ +""" +Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find +the one that is missing from the array. + +For example, +Given nums = [0, 1, 3] return 2. + +Note: +Your algorithm should run in linear runtime complexity. Could you implement it +using only constant extra space complexity? +""" + +class Solution(object): + def missingNumber(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + n = len(nums) + s = n * (n + 1) / 2 + res = 0 + for i in nums: + res += i + return s - res + +s = Solution() +a1 = [0, 1, 3] +print(s.missingNumber(a1)) diff --git a/missing_number/solution2.py b/missing_number/solution2.py new file mode 100644 index 0000000..cae7fde --- /dev/null +++ b/missing_number/solution2.py @@ -0,0 +1,44 @@ +""" +Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find +the one that is missing from the array. + +For example, +Given nums = [0, 1, 3] return 2. + +Note: +Your algorithm should run in linear runtime complexity. Could you implement it +using only constant extra space complexity? +""" + +# Alternative solution using a method similar to First Missing Positive + +class Solution(object): + def missingNumber(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + n = len(nums) + i = 0 + while i < n: + j = nums[i] + if nums[i] != i and j < n: + nums[i], nums[j] = nums[j], nums[i] + else: + i += 1 + for i, e in enumerate(nums): + if i != e: + return i + else: + return n + + +a0 = [0] +a1 = [0, 1, 3] +a2 = [3, 0, 1] +a3 = [3, 5, 1, 2, 0] +s = Solution() +print(s.missingNumber(a0)) +print(s.missingNumber(a1)) +print(s.missingNumber(a2)) +print(s.missingNumber(a3)) diff --git a/remove_element/solution.py b/remove_element/solution.py index 49c4e25..45c6de0 100644 --- a/remove_element/solution.py +++ b/remove_element/solution.py @@ -1,3 +1,11 @@ +""" +Given an array and a value, remove all instances of that value in place and +return the new length. + +The order of elements can be changed. It doesn't matter what you leave beyond +the new length. +""" + class Solution: # @param A a list of integers # @param elem an integer, value need to be removed From 64280c9ae4b2682acd691c4fa748d7e8be894062 Mon Sep 17 00:00:00 2001 From: Shichao An Date: Mon, 24 Aug 2015 19:09:22 -0700 Subject: [PATCH 09/35] Added kth largest element in an array --- kth_largest_element_in_an_array/solution.py | 31 +++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 kth_largest_element_in_an_array/solution.py diff --git a/kth_largest_element_in_an_array/solution.py b/kth_largest_element_in_an_array/solution.py new file mode 100644 index 0000000..976ef92 --- /dev/null +++ b/kth_largest_element_in_an_array/solution.py @@ -0,0 +1,31 @@ +""" +Find the kth largest element in an unsorted array. Note that it is the kth +largest element in the sorted order, not the kth distinct element. + +For example, +Given [3,2,1,5,6,4] and k = 2, return 5. + +Note: +You may assume k is always valid, 1 <= k <= array's length +""" +import heapq + +class Solution(object): + def findKthLargest(self, nums, k): + """ + :type nums: List[int] + :type k: int + :rtype: int + """ + h = [] + for e in nums: + heapq.heappush(h, (-e, e)) + for i in range(k): + w, e = heapq.heappop(h) + if i == k - 1: + return e + +a1 = [3, 2, 1, 5, 6, 4] +s = Solution() +res = s.findKthLargest(a1, 2) +print(res) From d52133d8edc0ea7008405c575e0d5e1144b953e0 Mon Sep 17 00:00:00 2001 From: Shichao An Date: Wed, 26 Aug 2015 21:18:29 -0700 Subject: [PATCH 10/35] Added more problems --- find_peak_element/solution.py | 49 +++++++++++++++++++++++++ search_a_2d_matrix/solution.py | 20 ++++++++++ search_a_2d_matrix_ii/solution.py | 59 ++++++++++++++++++++++++++++++ search_for_a_range/solution.py | 13 +++++++ search_insert_position/solution.py | 52 ++++++++++++++++++++++++++ 5 files changed, 193 insertions(+) create mode 100644 find_peak_element/solution.py create mode 100644 search_a_2d_matrix_ii/solution.py create mode 100644 search_insert_position/solution.py diff --git a/find_peak_element/solution.py b/find_peak_element/solution.py new file mode 100644 index 0000000..e9147e0 --- /dev/null +++ b/find_peak_element/solution.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +""" +A peak element is an element that is greater than its neighbors. + +Given an input array where num[i] ≠ num[i+1], find a peak element and return +its index. + +The array may contain multiple peaks, in that case return the index to any one +of the peaks is fine. + +You may imagine that num[-1] = num[n] = -∞. + +For example, in array [1, 2, 3, 1], 3 is a peak element and your function +should return the index number 2. + +Note: +Your solution should be in logarithmic complexity. +""" + +class Solution(object): + def findPeakElement(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + n = len(nums) + left = 0 + right = n - 1 + if n == 1: + return 0 + while left <= right: + mid = left + (right - left) / 2 + if mid == 0 and nums[mid] > nums[mid + 1]: + return mid + elif mid == n - 1 and nums[mid] > nums[mid - 1]: + return mid + elif nums[mid - 1] < nums[mid] > nums[mid + 1]: + return mid + elif mid > 0 and nums[mid - 1] > nums[mid]: + right = mid - 1 + else: + left = mid + 1 + return mid + +a1 = [1, 2] +a2 = [1, 2, 1] +s = Solution() +print(s.findPeakElement(a1)) +print(s.findPeakElement(a2)) diff --git a/search_a_2d_matrix/solution.py b/search_a_2d_matrix/solution.py index a9b4552..d612d90 100644 --- a/search_a_2d_matrix/solution.py +++ b/search_a_2d_matrix/solution.py @@ -1,3 +1,23 @@ +# -*- coding: utf-8 -*- +""" +Write an efficient algorithm that searches for a value in an m x n matrix. +This matrix has the following properties: + +Integers in each row are sorted from left to right. +The first integer of each row is greater than the last integer of the previous +row. +For example, + +Consider the following matrix: + +[ + [1, 3, 5, 7], + [10, 11, 16, 20], + [23, 30, 34, 50] +] +Given target = 3, return true. +""" + class Solution: # @param matrix, a list of lists of integers # @param target, an integer diff --git a/search_a_2d_matrix_ii/solution.py b/search_a_2d_matrix_ii/solution.py new file mode 100644 index 0000000..124dbc6 --- /dev/null +++ b/search_a_2d_matrix_ii/solution.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +""" +Write an efficient algorithm that searches for a value in an m x n matrix. +This matrix has the following properties: + +Integers in each row are sorted in ascending from left to right. +Integers in each column are sorted in ascending from top to bottom. +For example, + +Consider the following matrix: + +[ + [1, 4, 7, 11, 15], + [2, 5, 8, 12, 19], + [3, 6, 9, 16, 22], + [10, 13, 14, 17, 24], + [18, 21, 23, 26, 30] +] +Given target = 5, return true. + +Given target = 20, return false. +""" + +class Solution(object): + def searchMatrix(self, matrix, target): + """ + :type matrix: List[List[int]] + :type target: int + :rtype: bool + """ + n = len(matrix) + m = len(matrix[0]) + if target < matrix[0][0] or target > matrix[n - 1][m - 1]: + return False + # Step-wise Linear Search from upper right + y = 0 + x = m - 1 + while x >= 0 and y <= n - 1: + if target == matrix[y][x]: + return True + elif target < matrix[y][x]: + x -= 1 + else: + y += 1 + return False + + +a1 = [ + [1, 4, 7, 11, 15], + [2, 5, 8, 12, 19], + [3, 6, 9, 16, 22], + [10, 13, 14, 17, 24], + [18, 21, 23, 26, 30] +] + +s = Solution() +print(s.searchMatrix(a1, 5)) +print(s.searchMatrix(a1, 20)) +print(s.searchMatrix(a1, 17)) diff --git a/search_for_a_range/solution.py b/search_for_a_range/solution.py index 3875ef4..c92cdd0 100644 --- a/search_for_a_range/solution.py +++ b/search_for_a_range/solution.py @@ -1,3 +1,16 @@ +""" +Given a sorted array of integers, find the starting and ending position of a +given target value. + +Your algorithm's runtime complexity must be in the order of O(log n). + +If the target is not found in the array, return [-1, -1]. + +For example, +Given [5, 7, 7, 8, 8, 10] and target value 8, +return [3, 4]. +""" + class Solution: # @param A, a list of integers # @param target, an integer to be searched diff --git a/search_insert_position/solution.py b/search_insert_position/solution.py new file mode 100644 index 0000000..9215eec --- /dev/null +++ b/search_insert_position/solution.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +""" +Given a sorted array and a target value, return the index if the target is +found. If not, return the index where it would be if it were inserted in +order. + +You may assume no duplicates in the array. + +Here are few examples. +[1,3,5,6], 5 → 2 +[1,3,5,6], 2 → 1 +[1,3,5,6], 7 → 4 +[1,3,5,6], 0 → 0 + +""" + +class Solution(object): + def searchInsert(self, nums, target): + """ + :type nums: List[int] + :type target: int + :rtype: int + """ + n = len(nums) + if not nums: + return 0 + else: + left = 0 + right = n - 1 + while left <= right: + mid = (left + right) / 2 + if nums[mid] == target: + return mid + elif (mid < n - 1 and nums[mid] < target + and nums[mid + 1] > target): + return mid + 1 + elif target < nums[mid]: + right = mid - 1 + else: + left = mid + 1 + if left > n - 1: + return n + elif right < 0: + return 0 + + +a = [1, 3, 5, 6] +s = Solution() +print(s.searchInsert(a, 5)) +print(s.searchInsert(a, 2)) +print(s.searchInsert(a, 7)) +print(s.searchInsert(a, 0)) From e7b22b6da6fbd97d0cd6a75a0e956448da258449 Mon Sep 17 00:00:00 2001 From: Shichao An Date: Thu, 27 Aug 2015 19:15:47 -0700 Subject: [PATCH 11/35] Added new problems and fixed --- balanced_binary_tree/solution.py | 7 +++ balanced_binary_tree/solution2.py | 7 +++ .../solution.py | 36 +++++++++++++ .../solution.py | 52 +++++++++++++++++++ .../solution.py | 52 +++++++++++++++++++ maximum_depth_of_binary_tree/solution.py | 7 +++ reverse_words_in_a_string/solution.py | 13 +++++ rotate_array/solution.py | 34 ++++++++++++ search_in_rotated_sorted_array/solution.py | 33 ++++++++---- search_in_rotated_sorted_array_ii/solution.py | 38 ++++++++++---- 10 files changed, 258 insertions(+), 21 deletions(-) create mode 100644 find_minimum_in_rotated_sorted_array/solution.py create mode 100644 find_minimum_in_rotated_sorted_array_ii/solution.py create mode 100644 lowest_common_ancestor_of_a_binary_tree/solution.py create mode 100644 rotate_array/solution.py diff --git a/balanced_binary_tree/solution.py b/balanced_binary_tree/solution.py index 3b49c77..9e80647 100644 --- a/balanced_binary_tree/solution.py +++ b/balanced_binary_tree/solution.py @@ -1,3 +1,10 @@ +""" +Given a binary tree, determine if it is height-balanced. + +For this problem, a height-balanced binary tree is defined as a binary tree in +which the depth of the two subtrees of every node never differ by more than 1. +""" + # Definition for a binary tree node # class TreeNode: # def __init__(self, x): diff --git a/balanced_binary_tree/solution2.py b/balanced_binary_tree/solution2.py index ecf37f4..1458e51 100644 --- a/balanced_binary_tree/solution2.py +++ b/balanced_binary_tree/solution2.py @@ -1,3 +1,10 @@ +""" +Given a binary tree, determine if it is height-balanced. + +For this problem, a height-balanced binary tree is defined as a binary tree in +which the depth of the two subtrees of every node never differ by more than 1. +""" + # Definition for a binary tree node # class TreeNode: # def __init__(self, x): diff --git a/find_minimum_in_rotated_sorted_array/solution.py b/find_minimum_in_rotated_sorted_array/solution.py new file mode 100644 index 0000000..42c4265 --- /dev/null +++ b/find_minimum_in_rotated_sorted_array/solution.py @@ -0,0 +1,36 @@ +""" +Suppose a sorted array is rotated at some pivot unknown to you beforehand. + +(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). + +Find the minimum element. + +You may assume no duplicate exists in the array. +""" + +class Solution(object): + def findMin(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + n = len(nums) + left = 0 + right = n - 1 + if n == 1 or nums[left] < nums[right]: + return nums[0] + while left <= right: + mid = left + (right - left) / 2 + if mid > 0 and nums[mid - 1] > nums[mid]: + return nums[mid] + # The minimum element is in the right side + elif nums[mid] > nums[right]: + left = mid + 1 + # The minimum element is in the left side + else: + right = mid - 1 + + +a1 = [4, 5, 6, 7, 0, 1, 2] +s = Solution() +print(s.findMin(a1)) diff --git a/find_minimum_in_rotated_sorted_array_ii/solution.py b/find_minimum_in_rotated_sorted_array_ii/solution.py new file mode 100644 index 0000000..928baf3 --- /dev/null +++ b/find_minimum_in_rotated_sorted_array_ii/solution.py @@ -0,0 +1,52 @@ +""" +Follow up for "Find Minimum in Rotated Sorted Array": +What if duplicates are allowed? + +Would this affect the run-time complexity? How and why? +Suppose a sorted array is rotated at some pivot unknown to you beforehand. + +(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). + +Find the minimum element. + +The array may contain duplicates. +""" + +class Solution(object): + def findMin(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + n = len(nums) + left = 0 + right = n - 1 + if n == 1: + return nums[0] + while left <= right: + mid = left + (right - left) / 2 + if mid > 0 and nums[mid - 1] > nums[mid]: + return nums[mid] + # The minimum element is in the right side + elif nums[mid] > nums[right]: + left = mid + 1 + # The minimum element is in the left side + elif nums[mid] < nums[right]: + right = mid - 1 + # The mid element equals the right element + else: + right -= 1 + # All elements are equal + return nums[0] + +a1 = [4, 5, 6, 7, 0, 1, 2] +a2 = [4, 5, 6, 7, 0, 1, 1, 1] +a3 = [4, 5, 6, 7, 0, 1, 2, 4] +a5 = [1, 1] +a4 = [1, 1, 1] +s = Solution() +print(s.findMin(a1)) +print(s.findMin(a2)) +print(s.findMin(a3)) +print(s.findMin(a4)) +print(s.findMin(a5)) diff --git a/lowest_common_ancestor_of_a_binary_tree/solution.py b/lowest_common_ancestor_of_a_binary_tree/solution.py new file mode 100644 index 0000000..6e9b3f6 --- /dev/null +++ b/lowest_common_ancestor_of_a_binary_tree/solution.py @@ -0,0 +1,52 @@ +""" +Given a binary tree, find the lowest common ancestor (LCA) of two given nodes +in the tree. + +According to the definition of LCA on Wikipedia: “The lowest common ancestor +is defined between two nodes v and w as the lowest node in T that has both v +and w as descendants (where we allow a node to be a descendant of itself).” + + _______3______ + / \ + ___5__ ___1__ + / \ / \ + 6 _2 0 8 + / \ + 7 4 +For example, the lowest common ancestor (LCA) of nodes 5 and 1 is 3. Another +example is LCA of nodes 5 and 4 is 5, since a node can be a descendant of +itself according to the LCA definition. +""" + +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def lowestCommonAncestor(self, root, p, q): + """ + :type root: TreeNode + :type p: TreeNode + :type q: TreeNode + :rtype: TreeNode + """ + # If both a and b exist in root, return their LCA; + # if either a or b exist in root, return whichever exists; + # if neither of them exist in root, return None + if root is None: + return None + elif root is p or root is q: + return root + else: + l = self.lowestCommonAncestor(root.left, p, q) + r = self.lowestCommonAncestor(root.right, p, q) + if l is not None and r is not None: + return root + else: + if l is not None: + return l + if r is not None: + return r diff --git a/maximum_depth_of_binary_tree/solution.py b/maximum_depth_of_binary_tree/solution.py index f91ca2d..e426de0 100644 --- a/maximum_depth_of_binary_tree/solution.py +++ b/maximum_depth_of_binary_tree/solution.py @@ -1,3 +1,10 @@ +""" +Given a binary tree, find its maximum depth. + +The maximum depth is the number of nodes along the longest path from the root +node down to the farthest leaf node. + +""" # Definition for a binary tree node # class TreeNode: # def __init__(self, x): diff --git a/reverse_words_in_a_string/solution.py b/reverse_words_in_a_string/solution.py index 9a50b9c..ba11f7c 100644 --- a/reverse_words_in_a_string/solution.py +++ b/reverse_words_in_a_string/solution.py @@ -1,3 +1,12 @@ +""" +Given an input string, reverse the string word by word. + +For example, +Given s = "the sky is blue", +return "blue is sky the". + +""" + class Solution: # @param s, a string # @return a string @@ -83,3 +92,7 @@ def reverseWords2(self, s): start += 1 q = start return ''.join(cs[left:right + 1]) + + +s = Solution() +print(s.reverseWords("the sky is blue")) diff --git a/rotate_array/solution.py b/rotate_array/solution.py new file mode 100644 index 0000000..4cc6d6f --- /dev/null +++ b/rotate_array/solution.py @@ -0,0 +1,34 @@ +""" +Rotate an array of n elements to the right by k steps. + +For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to +[5,6,7,1,2,3,4]. + +Note: +Try to come up as many solutions as you can, there are at least 3 different +ways to solve this problem. +""" + +class Solution(object): + def rotate(self, nums, k): + """ + :type nums: List[int] + :type k: int + :rtype: void Do not return anything, modify nums in-place instead. + """ + n = len(nums) + self.reverse(nums, 0, n - 1) + self.reverse(nums, 0, k - 1) + self.reverse(nums, k, n - 1) + + def reverse(self, nums, i, j): + while i < j: + nums[i], nums[j] = nums[j], nums[i] + i += 1 + j -= 1 + + +a = [1, 2, 3, 4, 5, 6, 7] +s = Solution() +s.rotate(a, 3) +print(a) diff --git a/search_in_rotated_sorted_array/solution.py b/search_in_rotated_sorted_array/solution.py index 0ae80f8..f54bf1a 100644 --- a/search_in_rotated_sorted_array/solution.py +++ b/search_in_rotated_sorted_array/solution.py @@ -1,23 +1,36 @@ -class Solution: - # @param A, a list of integers - # @param target, an integer to be searched - # @return an integer - def search(self, A, target): +""" +Suppose a sorted array is rotated at some pivot unknown to you beforehand. + +(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). + +You are given a target value to search. If found in the array return its +index, otherwise return -1. + +You may assume no duplicate exists in the array. +""" + +class Solution(object): + def search(self, nums, target): + """ + :type nums: List[int] + :type target: int + :rtype: int + """ left = 0 - right = len(A) - 1 + right = len(nums) - 1 while left <= right: mid = left + (right - left) / 2 - if target == A[mid]: + if target == nums[mid]: return mid # Left part is sorted - if A[mid] > A[right]: - if target < A[mid] and target >= A[left]: + elif nums[mid] > nums[right]: + if target < nums[mid] and target >= nums[left]: right = mid - 1 else: left = mid + 1 # Right part is sorted else: - if target > A[mid] and target <= A[right]: + if target > nums[mid] and target <= nums[right]: left = mid + 1 else: right = mid - 1 diff --git a/search_in_rotated_sorted_array_ii/solution.py b/search_in_rotated_sorted_array_ii/solution.py index 7e47ca7..3bc5643 100644 --- a/search_in_rotated_sorted_array_ii/solution.py +++ b/search_in_rotated_sorted_array_ii/solution.py @@ -1,23 +1,39 @@ -class Solution: - # @param A a list of integers - # @param target an integer - # @return a boolean - def search(self, A, target): +""" +Suppose a sorted array is rotated at some pivot unknown to you beforehand. + +(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). + +Follow up for "Search in Rotated Sorted Array": + +What if duplicates are allowed? + +Would this affect the run-time complexity? How and why? + +Write a function to determine if a given target is in the array. +""" + +class Solution(object): + def search(self, nums, target): + """ + :type nums: List[int] + :type target: int + :rtype: bool + """ left = 0 - right = len(A) - 1 + right = len(nums) - 1 while left <= right: mid = left + (right - left) / 2 - if target == A[mid]: + if target == nums[mid]: return True # Left part is sorted - if A[mid] > A[right]: - if target < A[mid] and target >= A[left]: + elif nums[mid] > nums[right]: + if target < nums[mid] and target >= nums[left]: right = mid - 1 else: left = mid + 1 # Right part is sorted - elif A[mid] < A[right]: - if target > A[mid] and target <= A[right]: + elif nums[mid] < nums[right]: + if target > nums[mid] and target <= nums[right]: left = mid + 1 else: right = mid - 1 From d42791502761a2a93fd1ceaec1d04a8d0ba8a2ab Mon Sep 17 00:00:00 2001 From: Shichao An Date: Fri, 28 Aug 2015 00:15:16 -0700 Subject: [PATCH 12/35] Added binary_tree_maximum_path_sum --- binary_tree_maximum_path_sum/solution.py | 47 ++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 binary_tree_maximum_path_sum/solution.py diff --git a/binary_tree_maximum_path_sum/solution.py b/binary_tree_maximum_path_sum/solution.py new file mode 100644 index 0000000..12e9ec5 --- /dev/null +++ b/binary_tree_maximum_path_sum/solution.py @@ -0,0 +1,47 @@ +""" +Given a binary tree, find the maximum path sum. + +The path may start and end at any node in the tree. + +For example: +Given the below binary tree, + + 1 + / \ + 2 3 +Return 6. +""" + +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def maxPathSum(self, root): + """ + :type root: TreeNode + :rtype: int + """ + max_res = [None] + res = self.max_sum(root, max_res) + return max(res, max_res[0]) + + def max_sum(self, root, max_res): + if root is None: + return 0 + else: + left_max = self.max_sum(root.left, max_res) + right_max = self.max_sum(root.right, max_res) + root_max = max(root.val, + root.val + left_max, + root.val + right_max) + if max_res[0] is not None: + max_res[0] = max(max_res[0], + root_max, + root.val + left_max + right_max) + else: + max_res[0] = max(root_max, root.val + left_max + right_max) + return root_max From 010930d2cf46e9fe21f2cbacdfdb0ee0ea5ceabf Mon Sep 17 00:00:00 2001 From: Shichao An Date: Fri, 28 Aug 2015 11:30:01 -0700 Subject: [PATCH 13/35] Added problem subjects --- binary_tree_level_order_traversal/solution.py | 18 ++++++++++++++++++ .../solution.py | 19 +++++++++++++++++++ .../solution.py | 19 +++++++++++++++++++ validate_binary_search_tree/solution.py | 12 ++++++++++++ validate_binary_search_tree/solution2.py | 12 ++++++++++++ validate_binary_search_tree/solution3.py | 12 ++++++++++++ 6 files changed, 92 insertions(+) diff --git a/binary_tree_level_order_traversal/solution.py b/binary_tree_level_order_traversal/solution.py index 60c20dd..a92f2c3 100644 --- a/binary_tree_level_order_traversal/solution.py +++ b/binary_tree_level_order_traversal/solution.py @@ -1,3 +1,21 @@ +""" +Given a binary tree, return the level order traversal of its nodes' values. +(ie, from left to right, level by level). + +For example: +Given binary tree {3,9,20,#,#,15,7}, + 3 + / \ + 9 20 + / \ + 15 7 +return its level order traversal as: +[ + [3], + [9,20], + [15,7] +] +""" # Definition for a binary tree node # class TreeNode: # def __init__(self, x): diff --git a/binary_tree_level_order_traversal_ii/solution.py b/binary_tree_level_order_traversal_ii/solution.py index 8b2b4d7..77042c0 100644 --- a/binary_tree_level_order_traversal_ii/solution.py +++ b/binary_tree_level_order_traversal_ii/solution.py @@ -1,3 +1,22 @@ +""" +Given a binary tree, return the bottom-up level order traversal of its nodes' +values. (ie, from left to right, level by level from leaf to root). + +For example: +Given binary tree {3,9,20,#,#,15,7}, + 3 + / \ + 9 20 + / \ + 15 7 +return its bottom-up level order traversal as: +[ + [15,7], + [9,20], + [3] +] +""" + # Definition for a binary tree node # class TreeNode: # def __init__(self, x): diff --git a/binary_tree_zigzag_level_order_traversal/solution.py b/binary_tree_zigzag_level_order_traversal/solution.py index a8d39a7..58ab290 100644 --- a/binary_tree_zigzag_level_order_traversal/solution.py +++ b/binary_tree_zigzag_level_order_traversal/solution.py @@ -1,3 +1,22 @@ +""" +Given a binary tree, return the zigzag level order traversal of its nodes' +values. (ie, from left to right, then right to left for the next level and +alternate between). + +For example: +Given binary tree {3,9,20,#,#,15,7}, + 3 + / \ + 9 20 + / \ + 15 7 +return its zigzag level order traversal as: +[ + [3], + [20,9], + [15,7] +] +""" # Definition for a binary tree node # class TreeNode: # def __init__(self, x): diff --git a/validate_binary_search_tree/solution.py b/validate_binary_search_tree/solution.py index 595a71f..8ac1d64 100644 --- a/validate_binary_search_tree/solution.py +++ b/validate_binary_search_tree/solution.py @@ -1,3 +1,15 @@ +""" +Given a binary tree, determine if it is a valid binary search tree (BST). + +Assume a BST is defined as follows: + +The left subtree of a node contains only nodes with keys less than the node's +key. +The right subtree of a node contains only nodes with keys greater than the +node's key. +Both the left and right subtrees must also be binary search trees. +""" + # Definition for a binary tree node # class TreeNode: # def __init__(self, x): diff --git a/validate_binary_search_tree/solution2.py b/validate_binary_search_tree/solution2.py index 099da55..1cafdc1 100644 --- a/validate_binary_search_tree/solution2.py +++ b/validate_binary_search_tree/solution2.py @@ -1,3 +1,15 @@ +""" +Given a binary tree, determine if it is a valid binary search tree (BST). + +Assume a BST is defined as follows: + +The left subtree of a node contains only nodes with keys less than the node's +key. +The right subtree of a node contains only nodes with keys greater than the +node's key. +Both the left and right subtrees must also be binary search trees. +""" + # Definition for a binary tree node # class TreeNode: # def __init__(self, x): diff --git a/validate_binary_search_tree/solution3.py b/validate_binary_search_tree/solution3.py index 795a90f..656b1a7 100644 --- a/validate_binary_search_tree/solution3.py +++ b/validate_binary_search_tree/solution3.py @@ -1,3 +1,15 @@ +""" +Given a binary tree, determine if it is a valid binary search tree (BST). + +Assume a BST is defined as follows: + +The left subtree of a node contains only nodes with keys less than the node's +key. +The right subtree of a node contains only nodes with keys greater than the +node's key. +Both the left and right subtrees must also be binary search trees. +""" + # Definition for a binary tree node # class TreeNode: # def __init__(self, x): From f98aa339c62a11a2aa55bf71cf7b5d68a643b4ce Mon Sep 17 00:00:00 2001 From: Shichao An Date: Fri, 28 Aug 2015 16:54:07 -0700 Subject: [PATCH 14/35] Added house robberr ii; added problem subject --- .../solution.py | 6 ++- house_robber_ii/solution.py | 45 +++++++++++++++++++ maximum_subarray/solution.py | 8 ++++ maximum_subarray/solution2.py | 8 ++++ recover_binary_search_tree/solution.py | 10 +++++ 5 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 house_robber_ii/solution.py diff --git a/convert_sorted_list_to_binary_search_tree/solution.py b/convert_sorted_list_to_binary_search_tree/solution.py index 79c66ee..77c7fe2 100644 --- a/convert_sorted_list_to_binary_search_tree/solution.py +++ b/convert_sorted_list_to_binary_search_tree/solution.py @@ -1,3 +1,7 @@ +""" +Given a singly linked list where elements are sorted in ascending order, +convert it to a height balanced BST. +""" # Definition for a binary tree node # class TreeNode: # def __init__(self, x): @@ -26,7 +30,7 @@ def sortedListToBST(self, head): prev = slow fast = fast.next.next slow = slow.next - if head == slow: + if head is slow: head = None if prev is not None: prev.next = None diff --git a/house_robber_ii/solution.py b/house_robber_ii/solution.py new file mode 100644 index 0000000..04d0cc2 --- /dev/null +++ b/house_robber_ii/solution.py @@ -0,0 +1,45 @@ +""" +Note: This is an extension of House Robber. + +After robbing those houses on that street, the thief has found himself a new +place for his thievery so that he will not get too much attention. This time, +all houses at this place are arranged in a circle. That means the first house +is the neighbor of the last one. Meanwhile, the security system for these +houses remain the same as for those in the previous street. + +Given a list of non-negative integers representing the amount of money of each +house, determine the maximum amount of money you can rob tonight without +alerting the police. +""" + +class Solution(object): + def rob(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + n = len(nums) + if n == 0: + return 0 + elif n == 1: + return nums[0] + return max(self.rob_aux(nums, 0), self.rob_aux(nums, 1)) + + def rob_aux(self, nums, left): + n = len(nums) - 1 + t = [0 for i in range(n + 1)] + if n == 0: + return t[n] + t[1] = nums[left] + if n <= 1: + return t[n] + t[2] = max(nums[left: left + 2]) + for i in range(3, n + 1): + t[i] = max(t[i - 2] + nums[left + i - 1], t[i - 1]) + return t[n] + +a1 = [1] +a2 = [4, 1, 6, 10, 5, 13, 2, 7] +s = Solution() +print(s.rob(a1)) +print(s.rob(a2)) diff --git a/maximum_subarray/solution.py b/maximum_subarray/solution.py index dff4df3..dbdcc7b 100644 --- a/maximum_subarray/solution.py +++ b/maximum_subarray/solution.py @@ -1,3 +1,11 @@ +""" +Find the contiguous subarray within an array (containing at least one number) +which has the largest sum. + +For example, given the array [−2,1,−3,4,−1,2,1,−5,4], +the contiguous subarray [4,−1,2,1] has the largest sum = 6. +""" + class Solution: # @param A, a list of integers # @return an integer diff --git a/maximum_subarray/solution2.py b/maximum_subarray/solution2.py index 8355aef..b7d19bc 100644 --- a/maximum_subarray/solution2.py +++ b/maximum_subarray/solution2.py @@ -1,3 +1,11 @@ +""" +Find the contiguous subarray within an array (containing at least one number) +which has the largest sum. + +For example, given the array [−2,1,−3,4,−1,2,1,−5,4], +the contiguous subarray [4,−1,2,1] has the largest sum = 6. +""" + class Solution: # @param A, a list of integers # @return an integer diff --git a/recover_binary_search_tree/solution.py b/recover_binary_search_tree/solution.py index 3116c3d..f1be087 100644 --- a/recover_binary_search_tree/solution.py +++ b/recover_binary_search_tree/solution.py @@ -1,3 +1,13 @@ +""" +Two elements of a binary search tree (BST) are swapped by mistake. + +Recover the tree without changing its structure. + +Note: +A solution using O(n) space is pretty straight forward. Could you devise a +constant space solution? +""" + # Definition for a binary tree node # class TreeNode: # def __init__(self, x): From 7c7010c08ed7e0333874c20c791b79bd8597696a Mon Sep 17 00:00:00 2001 From: Shichao An Date: Tue, 1 Sep 2015 19:19:50 -0700 Subject: [PATCH 15/35] Fixed util function and AC --- word_ladder/solution.py | 87 +++++++++++++++++++++++++---------------- 1 file changed, 53 insertions(+), 34 deletions(-) diff --git a/word_ladder/solution.py b/word_ladder/solution.py index f282df8..6fbbe47 100644 --- a/word_ladder/solution.py +++ b/word_ladder/solution.py @@ -1,42 +1,61 @@ -class Solution: - # @param start, a string - # @param end, a string - # @param dict, a set of string - # @return an integer - def ladderLength(self, start, end, dict): +""" +Given two words (beginWord and endWord), and a dictionary, find the length of +shortest transformation sequence from beginWord to endWord, such that: + +Only one letter can be changed at a time +Each intermediate word must exist in the dictionary +For example, + +Given: +start = "hit" +end = "cog" +dict = ["hot","dot","dog","lot","log"] +As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog", +return its length 5. + +Note: +Return 0 if there is no such transformation sequence. +All words have the same length. +All words contain only lowercase alphabetic characters. +""" + +class Solution(object): + def ladderLength(self, beginWord, endWord, wordDict): + """ + :type beginWord: str + :type endWord: str + :type wordDict: Set[str] + :rtype: int + """ queue = [] - queue.append(start) - prev = {} - prev[start] = None - # Remove words that are same as start - for word in set(dict): - if start == word: - dict.remove(start) - dict.add(end) + queue.append((beginWord, 0)) + self.letters = map(chr, range(ord('a'), ord('z') + 1)) + self.word_dict = wordDict + # Remove words that are same as beginWord + for word in set(wordDict): + if beginWord == word: + wordDict.remove(beginWord) + wordDict.add(endWord) while queue: cur = queue.pop(0) - for word in set(dict): # Iterate over the copy of dict - if self.is_adjacent(cur, word): - dict.remove(word) # Mark as visited - prev[word] = cur - queue.append(word) - if end not in prev: - return 0 - res = 1 - cur = end - while prev[cur] != start: - cur = prev[cur] - res += 1 - return res + 1 + if cur[0] == endWord: + return cur[1] + 1 + for word in self.get_adjacent(cur[0]): + wordDict.remove(word) # Mark as visited + queue.append((word, cur[1] + 1)) + return 0 - def is_adjacent(self, word1, word2): - count = 0 - n = len(word1) - for i in range(n): - if word1[i] != word2[i]: - count += 1 - return count == 1 + def get_adjacent(self, word1): + res = [] + for i, e in enumerate(word1): + for letter in self.letters: + word = word1[:i] + letter + word1[i + 1:] + if word in self.word_dict: + res.append(word) + return res s = Solution() print s.ladderLength("hit", "dow", set(["hot", "dot", "dog", "lot", "log"])) +print s.ladderLength("hit", "cog", set(["hot", "dot", "dog", "lot", "log"])) +print s.ladderLength("hit", "cog", set(["aos", "dis", "dog", "lot", "log"])) From 768050ca3a89c5392697ebce467320e1e00bcaaf Mon Sep 17 00:00:00 2001 From: Shichao An Date: Wed, 2 Sep 2015 18:23:54 -0700 Subject: [PATCH 16/35] Fixed solutions --- minimum_path_sum/solution.py | 7 ++++ minimum_path_sum/solution2.py | 7 ++++ search_for_a_range/solution2.py | 60 +++++++++++++++++++++++++++++++++ triangle/solution.py | 18 ++++++++++ triangle/solution2.py | 57 +++++++++++++++++++++++++++++++ unique_paths/solution.py | 11 ++++++ unique_paths_ii/solution.py | 21 ++++++++++++ unique_paths_ii/solution2.py | 21 ++++++++++++ word_break/solution.py | 35 +++++++++++++++++++ 9 files changed, 237 insertions(+) create mode 100644 search_for_a_range/solution2.py create mode 100644 triangle/solution2.py create mode 100644 word_break/solution.py diff --git a/minimum_path_sum/solution.py b/minimum_path_sum/solution.py index f5b22a4..d05797d 100644 --- a/minimum_path_sum/solution.py +++ b/minimum_path_sum/solution.py @@ -1,3 +1,10 @@ +""" +Given a m x n grid filled with non-negative numbers, find a path from top left +to bottom right which minimizes the sum of all numbers along its path. + +Note: You can only move either down or right at any point in time. +""" + class Solution: # @param grid, a list of lists of integers # @return an integer diff --git a/minimum_path_sum/solution2.py b/minimum_path_sum/solution2.py index 9c212f9..45cd575 100644 --- a/minimum_path_sum/solution2.py +++ b/minimum_path_sum/solution2.py @@ -1,3 +1,10 @@ +""" +Given a m x n grid filled with non-negative numbers, find a path from top left +to bottom right which minimizes the sum of all numbers along its path. + +Note: You can only move either down or right at any point in time. +""" + class Solution: # @param grid, a list of lists of integers # @return an integer diff --git a/search_for_a_range/solution2.py b/search_for_a_range/solution2.py new file mode 100644 index 0000000..eca7d2a --- /dev/null +++ b/search_for_a_range/solution2.py @@ -0,0 +1,60 @@ +""" +Given a sorted array of integers, find the starting and ending position of a +given target value. + +Your algorithm's runtime complexity must be in the order of O(log n). + +If the target is not found in the array, return [-1, -1]. + +For example, +Given [5, 7, 7, 8, 8, 10] and target value 8, +return [3, 4]. +""" + +class Solution(object): + def searchRange(self, nums, target): + """ + :type nums: List[int] + :type target: int + :rtype: List[int] + """ + n = len(nums) + left = 0 + right = n - 1 + left_res = -1 + right_res = -1 + # Search for left bound (first occurence of target) + while left + 1 < right: + mid = left + (right - left) / 2 + if target > nums[mid]: + left = mid + else: + right = mid + if nums[left] == target: + left_res = left + elif nums[right] == target: + left_res = right + else: + return [-1, -1] + + # Search for right bound (last occurence of target) + left = 0 + right = n - 1 + while left + 1 < right: + mid = left + (right - left) / 2 + if target >= nums[mid]: + left = mid + else: + right = mid + if nums[right] == target: + right_res = right + elif nums[left] == target: + right_res = left + return [left_res, right_res] + + +a1 = [5, 7, 7, 8, 8, 10] +a2 = [2, 2] +s = Solution() +print(s.searchRange(a1, 8)) +print(s.searchRange(a2, 2)) diff --git a/triangle/solution.py b/triangle/solution.py index 51c06db..b054547 100644 --- a/triangle/solution.py +++ b/triangle/solution.py @@ -1,3 +1,21 @@ +""" +Given a triangle, find the minimum path sum from top to bottom. Each step you +may move to adjacent numbers on the row below. + +For example, given the following triangle +[ + [2], + [3,4], + [6,5,7], + [4,1,8,3] +] +The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11). + +Note: +Bonus point if you are able to do this using only O(n) extra space, where n is +the total number of rows in the triangle. +""" + class Solution: # @param triangle, a list of lists of integers # @return an integer diff --git a/triangle/solution2.py b/triangle/solution2.py new file mode 100644 index 0000000..43ba422 --- /dev/null +++ b/triangle/solution2.py @@ -0,0 +1,57 @@ +""" +Given a triangle, find the minimum path sum from top to bottom. Each step you +may move to adjacent numbers on the row below. + +For example, given the following triangle +[ + [2], + [3,4], + [6,5,7], + [4,1,8,3] +] +The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11). + +Note: +Bonus point if you are able to do this using only O(n) extra space, where n is +the total number of rows in the triangle. +""" + +class Solution(object): + def minimumTotal(self, triangle): + """ + :type triangle: List[List[int]] + :rtype: int + """ + n = len(triangle) + m = 0 + res = None + for i, row in enumerate(triangle): + m = len(row) + if i > 0: + for j, col in enumerate(row): + if 0 < j < m - 1: + triangle[i][j] += min(triangle[i - 1][j - 1], + triangle[i - 1][j]) + elif j == 0: + triangle[i][j] += triangle[i - 1][j] + # j == m - 1 + else: + triangle[i][j] += triangle[i - 1][j - 1] + if i == n - 1: + for col in row: + if res is None: + res = col + else: + res = min(col, res) + return res + + +a1 = [ + [2], + [3, 4], + [6, 5, 7], + [4, 1, 8, 3] +] + +s = Solution() +print(s.minimumTotal(a1)) diff --git a/unique_paths/solution.py b/unique_paths/solution.py index 7f1857b..9bb4a3d 100644 --- a/unique_paths/solution.py +++ b/unique_paths/solution.py @@ -1,3 +1,14 @@ +""" +A robot is located at the top-left corner of a m x n grid (marked 'Start' in +the diagram below). + +The robot can only move either down or right at any point in time. The robot +is trying to reach the bottom-right corner of the grid (marked 'Finish' in the +diagram below). + +How many possible unique paths are there? +""" + class Solution: # @return an integer def uniquePaths(self, m, n): diff --git a/unique_paths_ii/solution.py b/unique_paths_ii/solution.py index f348aec..e8154b5 100644 --- a/unique_paths_ii/solution.py +++ b/unique_paths_ii/solution.py @@ -1,3 +1,24 @@ +""" +Follow up for "Unique Paths": + +Now consider if some obstacles are added to the grids. How many unique paths +would there be? + +An obstacle and empty space is marked as 1 and 0 respectively in the grid. + +For example, +There is one obstacle in the middle of a 3x3 grid as illustrated below. + +[ + [0,0,0], + [0,1,0], + [0,0,0] +] +The total number of unique paths is 2. + +Note: m and n will be at most 100. +""" + class Solution: # @param obstacleGrid, a list of lists of integers # @return an integer diff --git a/unique_paths_ii/solution2.py b/unique_paths_ii/solution2.py index a48e8e2..80b49c1 100644 --- a/unique_paths_ii/solution2.py +++ b/unique_paths_ii/solution2.py @@ -1,3 +1,24 @@ +""" +Follow up for "Unique Paths": + +Now consider if some obstacles are added to the grids. How many unique paths +would there be? + +An obstacle and empty space is marked as 1 and 0 respectively in the grid. + +For example, +There is one obstacle in the middle of a 3x3 grid as illustrated below. + +[ + [0,0,0], + [0,1,0], + [0,0,0] +] +The total number of unique paths is 2. + +Note: m and n will be at most 100. +""" + class Solution: # @param obstacleGrid, a list of lists of integers # @return an integer diff --git a/word_break/solution.py b/word_break/solution.py new file mode 100644 index 0000000..b5f51e0 --- /dev/null +++ b/word_break/solution.py @@ -0,0 +1,35 @@ +""" +Given a string s and a dictionary of words dict, determine if s can be +segmented into a space-separated sequence of one or more dictionary words. + +For example, given +s = "leetcode", +dict = ["leet", "code"]. + +Return true because "leetcode" can be segmented as "leet code". +""" + +class Solution(object): + def wordBreak(self, s, wordDict): + """ + :type s: str + :type wordDict: Set[str] + :rtype: bool + """ + t = set() + return self.word_break_aux(s, wordDict, t) + + def word_break_aux(self, s, wordDict, t): + if not s: + return True + if s in t: + return True + else: + for i, c in enumerate(s): + word = s[:i + 1] + rest = s[i + 1:] + if word in wordDict and self.wordBreak(rest, wordDict): + t.add(s) + print(t) + return True + return False From b5852fda142bc38a61d307abc96932ea50668ccc Mon Sep 17 00:00:00 2001 From: Shichao An Date: Wed, 2 Sep 2015 18:53:04 -0700 Subject: [PATCH 17/35] Fixed --- word_break/solution.py | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/word_break/solution.py b/word_break/solution.py index b5f51e0..a635bfa 100644 --- a/word_break/solution.py +++ b/word_break/solution.py @@ -16,20 +16,15 @@ def wordBreak(self, s, wordDict): :type wordDict: Set[str] :rtype: bool """ - t = set() - return self.word_break_aux(s, wordDict, t) - - def word_break_aux(self, s, wordDict, t): - if not s: - return True - if s in t: - return True - else: - for i, c in enumerate(s): - word = s[:i + 1] - rest = s[i + 1:] - if word in wordDict and self.wordBreak(rest, wordDict): - t.add(s) - print(t) - return True - return False + n = len(s) + # t[i] indicates s[:i + 1] is such a string + t = [False for i in range(n)] + for i in range(n): + if s[:i + 1] in wordDict: + t[i] = True + else: + for j in range(i + 1): + if t[j] is True and s[j + 1:i + 1] in wordDict: + t[i] = True + break + return t[-1] From 5d7d548962607f2efdece41b5a7530365c3a0bf8 Mon Sep 17 00:00:00 2001 From: Shichao An Date: Thu, 3 Sep 2015 00:29:45 -0700 Subject: [PATCH 18/35] Fixed and added word break ii (No AC) --- word_break/solution.py | 2 +- word_break/solution2.py | 44 ++++++++++++++++++++++++++++++++ word_break_ii/solution.py | 47 +++++++++++++++++++++++++++++++++++ word_break_ii/solution2.py | 51 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 word_break/solution2.py create mode 100644 word_break_ii/solution.py create mode 100644 word_break_ii/solution2.py diff --git a/word_break/solution.py b/word_break/solution.py index a635bfa..e9d7a91 100644 --- a/word_break/solution.py +++ b/word_break/solution.py @@ -23,7 +23,7 @@ def wordBreak(self, s, wordDict): if s[:i + 1] in wordDict: t[i] = True else: - for j in range(i + 1): + for j in range(i): if t[j] is True and s[j + 1:i + 1] in wordDict: t[i] = True break diff --git a/word_break/solution2.py b/word_break/solution2.py new file mode 100644 index 0000000..aba8fa2 --- /dev/null +++ b/word_break/solution2.py @@ -0,0 +1,44 @@ +""" +Given a string s and a dictionary of words dict, determine if s can be +segmented into a space-separated sequence of one or more dictionary words. + +For example, given +s = "leetcode", +dict = ["leet", "code"]. + +Return true because "leetcode" can be segmented as "leet code". +""" + +class Solution(object): + def wordBreak(self, s, wordDict): + """ + :type s: str + :type wordDict: Set[str] + :rtype: bool + """ + n = len(s) + t = [None for i in range(n)] + return self.word_break_aux(s, wordDict, n - 1, t) + + def word_break_aux(self, s, wordDict, i, t): + """ + Determine if s[:i + 1] can be segmented by dict wordDict + """ + if s[:i + 1] in wordDict: + return True + elif t[i] is not None: + return t[i] + else: + for j in range(i): + if (self.word_break_aux(s, wordDict, j, t) is True + and s[j + 1:i + 1] in wordDict): + t[i] = True + return True + else: + t[i] = False + return False + + +s = Solution() +print(s.wordBreak('leetcode', ['leet', 'code'])) +print(s.wordBreak('leetcode', ['lee', 'code'])) diff --git a/word_break_ii/solution.py b/word_break_ii/solution.py new file mode 100644 index 0000000..efa8551 --- /dev/null +++ b/word_break_ii/solution.py @@ -0,0 +1,47 @@ +""" +Given a string s and a dictionary of words dict, add spaces in s to construct +a sentence where each word is a valid dictionary word. + +Return all such possible sentences. + +For example, given +s = "catsanddog", +dict = ["cat", "cats", "and", "sand", "dog"]. + +A solution is ["cats and dog", "cat sand dog"]. +""" + +class Solution(object): + def wordBreak(self, s, wordDict): + """ + :type s: str + :type wordDict: Set[str] + :rtype: List[str] + + Time Limit Exceeded + """ + cand = [] + res = [] + self.word_break_aux(s, wordDict, cand, res) + return res + + def word_break_aux(self, s, wordDict, cand, res): + """ + Determine if s[:i + 1] can be segmented by dict wordDict + """ + if not s: + res.append(' '.join(cand)) + else: + for i, c in enumerate(s): + word = s[:i + 1] + rest = s[i + 1:] + if word in wordDict: + cand.append(word) + self.word_break_aux(rest, wordDict, cand, res) + cand.pop() + + +s1 = "catsanddog" +d1 = ["cat", "cats", "and", "sand", "dog"] +s = Solution() +print(s.wordBreak(s1, d1)) diff --git a/word_break_ii/solution2.py b/word_break_ii/solution2.py new file mode 100644 index 0000000..70834af --- /dev/null +++ b/word_break_ii/solution2.py @@ -0,0 +1,51 @@ +""" +Given a string s and a dictionary of words dict, add spaces in s to construct +a sentence where each word is a valid dictionary word. + +Return all such possible sentences. + +For example, given +s = "catsanddog", +dict = ["cat", "cats", "and", "sand", "dog"]. + +A solution is ["cats and dog", "cat sand dog"]. +""" + +class Solution(object): + def wordBreak(self, s, wordDict): + """ + :type s: str + :type wordDict: Set[str] + :rtype: bool + """ + n = len(s) + t = [None for i in range(n)] + res = self.word_break_aux(s, wordDict, n - 1, t) + return res + + def word_break_aux(self, s, wordDict, i, t): + """ + Determine if s[:i + 1] can be segmented by dict wordDict + """ + if s[:i + 1] in wordDict: + t[i] = [s[:i + 1]] + return t[i] + elif t[i] is not None: + return t[i] + else: + res = [] + for j in range(i): + rest = self.word_break_aux(s, wordDict, j, t) + word = s[j + 1:i + 1] + if rest and word in wordDict: + for r in rest: + res.append(r + ' ' + word) + t[i] = res + return t[i] + + +s1 = "catsanddog" +d1 = ["cat", "cats", "and", "sand", "dog"] +s = Solution() +print(s.wordBreak(s1, d1)) +print(s.wordBreak('leetcode', ['leet', 'code'])) From a84051569cd92d37889a3ba4aae1f9e81a451ee7 Mon Sep 17 00:00:00 2001 From: Shichao An Date: Thu, 3 Sep 2015 11:58:11 -0700 Subject: [PATCH 19/35] Added problem subjects --- climbing_stairs/solution2.py | 7 +++++++ jump_game/solution.py | 16 ++++++++++++++++ jump_game/solution2.py | 17 +++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/climbing_stairs/solution2.py b/climbing_stairs/solution2.py index 0683a79..8452c0b 100644 --- a/climbing_stairs/solution2.py +++ b/climbing_stairs/solution2.py @@ -1,3 +1,10 @@ +""" +You are climbing a stair case. It takes n steps to reach to the top. + +Each time you can either climb 1 or 2 steps. In how many distinct ways can you +climb to the top? +""" + class Solution: # @param n, an integer # @return an integer diff --git a/jump_game/solution.py b/jump_game/solution.py index 47237f9..a100b30 100644 --- a/jump_game/solution.py +++ b/jump_game/solution.py @@ -1,3 +1,18 @@ +""" +Given an array of non-negative integers, you are initially positioned at the +first index of the array. + +Each element in the array represents your maximum jump length at that +position. + +Determine if you are able to reach the last index. + +For example: +A = [2,3,1,1,4], return true. + +A = [3,2,1,0,4], return false. +""" + class Solution: # @param A, a list of integers # @return a boolean @@ -7,6 +22,7 @@ def canJump(self, A): return True t = 0 # Number of remaining steps for i in range(1, n): + # t is max number of steps that remained if reaching A[i] t = max(t, A[i - 1]) - 1 if t < 0: return False diff --git a/jump_game/solution2.py b/jump_game/solution2.py index f09c56b..200e9a4 100644 --- a/jump_game/solution2.py +++ b/jump_game/solution2.py @@ -1,3 +1,18 @@ +""" +Given an array of non-negative integers, you are initially positioned at the +first index of the array. + +Each element in the array represents your maximum jump length at that +position. + +Determine if you are able to reach the last index. + +For example: +A = [2,3,1,1,4], return true. + +A = [3,2,1,0,4], return false. +""" + class Solution: # @param A, a list of integers # @return a boolean @@ -5,9 +20,11 @@ def canJump(self, A): n = len(A) if n == 1: return True + # d[i] is the max index A[i] can reach in A d = [i + A[i] for i in range(n)] reach = n - 1 for i in range(1, n): + # j is from n - 1 to 0 j = n - 1 - i if d[j] >= reach: reach = j From 8df9c72d3011c215c401bf0e2ed51abfa96dd245 Mon Sep 17 00:00:00 2001 From: Shichao An Date: Thu, 3 Sep 2015 19:12:01 -0700 Subject: [PATCH 20/35] Added new problems --- add_digits/solution.py | 30 ++++++++++ bitwise_and_of_numbers_range/solution.py | 25 ++++++++ different_ways_to_add_parentheses/solution.py | 60 +++++++++++++++++++ happy_number/solution.py | 44 ++++++++++++++ isomorphic_strings/solution.py | 50 ++++++++++++++++ jump_game_ii/solution.py | 36 ++++++++--- jump_game_ii/solution2.py | 16 +++++ jump_game_ii/solution3.py | 44 ++++++++++++++ product_of_array_except_self/solution.py | 49 +++++++++++++++ product_of_array_except_self/solution2.py | 45 ++++++++++++++ product_of_array_except_self/solution3.py | 50 ++++++++++++++++ product_of_array_except_self/solution4.py | 49 +++++++++++++++ 12 files changed, 489 insertions(+), 9 deletions(-) create mode 100644 add_digits/solution.py create mode 100644 bitwise_and_of_numbers_range/solution.py create mode 100644 different_ways_to_add_parentheses/solution.py create mode 100644 happy_number/solution.py create mode 100644 isomorphic_strings/solution.py create mode 100644 jump_game_ii/solution3.py create mode 100644 product_of_array_except_self/solution.py create mode 100644 product_of_array_except_self/solution2.py create mode 100644 product_of_array_except_self/solution3.py create mode 100644 product_of_array_except_self/solution4.py diff --git a/add_digits/solution.py b/add_digits/solution.py new file mode 100644 index 0000000..2767747 --- /dev/null +++ b/add_digits/solution.py @@ -0,0 +1,30 @@ +""" +Given a non-negative integer num, repeatedly add all its digits until the +result has only one digit. + +For example: + +Given num = 38, the process is like: 3 + 8 = 11, 1 + 1 = 2. Since 2 has only +one digit, return it. + +Follow up: +Could you do it without any loop/recursion in O(1) runtime? +""" + +class Solution(object): + def addDigits(self, num): + """ + :type num: int + :rtype: int + """ + while num / 10: + d = 0 + while num > 0: + d += num % 10 + num /= 10 + num = d + return num + + +s = Solution() +print(s.addDigits(38)) diff --git a/bitwise_and_of_numbers_range/solution.py b/bitwise_and_of_numbers_range/solution.py new file mode 100644 index 0000000..e0c59ee --- /dev/null +++ b/bitwise_and_of_numbers_range/solution.py @@ -0,0 +1,25 @@ +""" +Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND +of all numbers in this range, inclusive. + +For example, given the range [5, 7], you should return 4. +""" + +class Solution(object): + def rangeBitwiseAnd(self, m, n): + """ + :type m: int + :type n: int + :rtype: int + """ + shift = 0 + while n > m: + shift += 1 + m = m >> 1 + n = n >> 1 + return m << shift + + +s = Solution() +print(s.rangeBitwiseAnd(5, 6)) +print(s.rangeBitwiseAnd(0, 2147483647)) diff --git a/different_ways_to_add_parentheses/solution.py b/different_ways_to_add_parentheses/solution.py new file mode 100644 index 0000000..8a4ceef --- /dev/null +++ b/different_ways_to_add_parentheses/solution.py @@ -0,0 +1,60 @@ +""" +Given a string of numbers and operators, return all possible results from +computing all the different possible ways to group numbers and operators. The +valid operators are +, - and *. + + +Example 1 +Input: "2-1-1". + +((2-1)-1) = 0 +(2-(1-1)) = 2 +Output: [0, 2] + + +Example 2 +Input: "2*3-4*5" + +(2*(3-(4*5))) = -34 +((2*3)-(4*5)) = -14 +((2*(3-4))*5) = -10 +(2*((3-4)*5)) = -10 +(((2*3)-4)*5) = 10 +Output: [-34, -14, -10, -10, 10] +""" + +class Solution(object): + def diffWaysToCompute(self, input): + """ + :type input: str + :rtype: List[int] + """ + self.operators = set(['+', '-', '*']) + return self.diff_ways(input) + + def calculate(self, a, b, operator): + return eval('%d %s %d' % (a, operator, b)) + + def diff_ways(self, inp): + if not inp: + return [] + elif inp.isdigit(): + return [int(inp)] + else: + res = [] + for i, c in enumerate(inp): + if c in self.operators: + left = self.diff_ways(inp[:i]) + right = self.diff_ways(inp[i + 1:]) + for l in left: + for r in right: + s = self.calculate(l, r, c) + res.append(s) + return res + + +s1 = '2*3-4*5' +s2 = '11' +s = Solution() +print(s.diffWaysToCompute(s1)) +print(s.diffWaysToCompute(s2)) diff --git a/happy_number/solution.py b/happy_number/solution.py new file mode 100644 index 0000000..7ce3efd --- /dev/null +++ b/happy_number/solution.py @@ -0,0 +1,44 @@ +""" +Write an algorithm to determine if a number is "happy". + +A happy number is a number defined by the following process: Starting with any +positive integer, replace the number by the sum of the squares of its digits, +and repeat the process until the number equals 1 (where it will stay), or it +loops endlessly in a cycle which does not include 1. Those numbers for which +this process ends in 1 are happy numbers. + +Example: 19 is a happy number + +1^2 + 9^2 = 82 +8^2 + 2^2 = 68 +6^2 + 8^2 = 100 +1^2 + 0^2 + 0^2 = 1 +""" + +class Solution(object): + def isHappy(self, n): + """ + :type n: int + :rtype: bool + """ + + # Use set d to check endless loop + d = set() + while n not in d: + d.add(n) + t = n + s = 0 # sum + while t != 0: + digit = (t % 10) + s += digit * digit + t /= 10 + n = s + if n == 1: + return True + return False + + +s = Solution() +print(s.isHappy(19)) +print(s.isHappy(1)) +print(s.isHappy(20)) diff --git a/isomorphic_strings/solution.py b/isomorphic_strings/solution.py new file mode 100644 index 0000000..cce7359 --- /dev/null +++ b/isomorphic_strings/solution.py @@ -0,0 +1,50 @@ +""" +Given two strings s and t, determine if they are isomorphic. + +Two strings are isomorphic if the characters in s can be replaced to get t. + +All occurrences of a character must be replaced with another character while +preserving the order of characters. No two characters may map to the same +character but a character may map to itself. + +For example, +Given "egg", "add", return true. + +Given "foo", "bar", return false. + +Given "paper", "title", return true. + +Note: +You may assume both s and t have the same length. +""" + +class Solution(object): + def isIsomorphic(self, s, t): + """ + :type s: str + :type t: str + :rtype: bool + """ + d = {} + for i, c in enumerate(s): + if c not in d: + d[c] = t[i] + else: + if d[c] != t[i]: + return False + d = {} + for i, c in enumerate(t): + if c not in d: + d[c] = s[i] + else: + if d[c] != s[i]: + return False + return True + + +s = Solution() +f = s.isIsomorphic +print(f('ab', 'aa')) +print(f('egg', 'add')) +print(f('foo', 'bar')) +print(f('paper', 'title')) diff --git a/jump_game_ii/solution.py b/jump_game_ii/solution.py index e2af56f..3a37b24 100644 --- a/jump_game_ii/solution.py +++ b/jump_game_ii/solution.py @@ -1,20 +1,38 @@ +""" +Given an array of non-negative integers, you are initially positioned at the +first index of the array. + +Each element in the array represents your maximum jump length at that +position. + +Your goal is to reach the last index in the minimum number of jumps. + +For example: +Given array A = [2,3,1,1,4] + +The minimum number of jumps to reach the last index is 2. (Jump 1 step from +index 0 to 1, then 3 steps to the last index.) +""" + class Solution: - # @param A, a list of integers - # @return an integer - def jump(self, A): - n = len(A) - if len(A) == 1: + def jump(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + n = len(nums) + if n == 1: return 0 start = 1 - end = A[0] # `end` is A[start - 1] - res = 1 # At least one step if len(A) > 1 + end = nums[0] # `end` is nums[start - 1] + res = 1 # At least one step if len(nums) > 1 reached = False while end < n - 1: res += 1 max_end = end # `end` for the next loop for i in range(start, end + 1): - if i + A[i] > max_end: - max_end = i + A[i] + if i + nums[i] > max_end: + max_end = i + nums[i] reached = True if not reached: return -1 diff --git a/jump_game_ii/solution2.py b/jump_game_ii/solution2.py index 3d5fd18..16d7ad1 100644 --- a/jump_game_ii/solution2.py +++ b/jump_game_ii/solution2.py @@ -1,3 +1,19 @@ +""" +Given an array of non-negative integers, you are initially positioned at the +first index of the array. + +Each element in the array represents your maximum jump length at that +position. + +Your goal is to reach the last index in the minimum number of jumps. + +For example: +Given array A = [2,3,1,1,4] + +The minimum number of jumps to reach the last index is 2. (Jump 1 step from +index 0 to 1, then 3 steps to the last index.) +""" + class Solution: # @param A, a list of integers # @return an integer diff --git a/jump_game_ii/solution3.py b/jump_game_ii/solution3.py new file mode 100644 index 0000000..391b909 --- /dev/null +++ b/jump_game_ii/solution3.py @@ -0,0 +1,44 @@ +""" +Given an array of non-negative integers, you are initially positioned at the +first index of the array. + +Each element in the array represents your maximum jump length at that +position. + +Your goal is to reach the last index in the minimum number of jumps. + +For example: +Given array A = [2,3,1,1,4] + +The minimum number of jumps to reach the last index is 2. (Jump 1 step from +index 0 to 1, then 3 steps to the last index.) +""" + +class Solution(object): + def jump(self, nums): + """ + :type nums: List[int] + :rtype: int + + Time Limit Exceeded + """ + n = len(nums) + # t[i] means mininum number of jumps to nums[i] + t = [-1 for i in range(n)] + t[0] = 0 + if n == 1: + return 1 + for i in range(n): + steps = nums[i] + end = min(i + steps, n - 1) + for j in range(i + 1, end + 1): + if t[j] == -1: + t[j] = t[i] + 1 + else: + t[j] = min(t[i] + 1, t[j]) + return t[-1] + + +a1 = [2, 3, 1, 1, 4] +s = Solution() +print(s.jump(a1)) diff --git a/product_of_array_except_self/solution.py b/product_of_array_except_self/solution.py new file mode 100644 index 0000000..f947e38 --- /dev/null +++ b/product_of_array_except_self/solution.py @@ -0,0 +1,49 @@ +""" +Given an array of n integers where n > 1, nums, return an array output such +that output[i] is equal to the product of all the elements of nums except +nums[i]. + +Solve it without division and in O(n). + +For example, given [1,2,3,4], return [24,12,8,6]. + +Follow up: +Could you solve it with constant space complexity? (Note: The output array +does not count as extra space for the purpose of space complexity analysis.) +""" + +class Solution(object): + def productExceptSelf(self, nums): + """ + :type nums: List[int] + :rtype: List[int] + + Memory Limit Exceeded + """ + if not nums: + return [] + elif len(nums) == 1: + return [1] + elif len(nums) == 2: + return nums[::-1] + else: + m = 1 + rest = nums[1:] + for c in rest: + m *= c + res = [m] + for r in self.productExceptSelf(rest): + res.append(r * nums[0]) + return res + + +a1 = [1, 2, 3] +a2 = [2, 3, 4] +a3 = [1, 2, 3, 4] +a4 = [2, 3, 4, 5] + +s = Solution() +print(s.productExceptSelf(a1)) +print(s.productExceptSelf(a2)) +print(s.productExceptSelf(a3)) +print(s.productExceptSelf(a4)) diff --git a/product_of_array_except_self/solution2.py b/product_of_array_except_self/solution2.py new file mode 100644 index 0000000..6305c06 --- /dev/null +++ b/product_of_array_except_self/solution2.py @@ -0,0 +1,45 @@ +""" +Given an array of n integers where n > 1, nums, return an array output such +that output[i] is equal to the product of all the elements of nums except +nums[i]. + +Solve it without division and in O(n). + +For example, given [1,2,3,4], return [24,12,8,6]. + +Follow up: +Could you solve it with constant space complexity? (Note: The output array +does not count as extra space for the purpose of space complexity analysis.) +""" + +class Solution(object): + def productExceptSelf(self, nums): + """ + :type nums: List[int] + :rtype: List[int] + + Time Limit Exceeded + """ + n = len(nums) + res = [1 for i in range(n)] + # product of nums[0..i - 1] + product = 1 + for i in range(1, n): + for j in range(i): + res[j] *= nums[i] + if i > 0: + product *= nums[i - 1] + res[i] = product + return res + + +a1 = [1, 2, 3] +a2 = [2, 3, 4] +a3 = [1, 2, 3, 4] +a4 = [2, 3, 4, 5] + +s = Solution() +print(s.productExceptSelf(a1)) +print(s.productExceptSelf(a2)) +print(s.productExceptSelf(a3)) +print(s.productExceptSelf(a4)) diff --git a/product_of_array_except_self/solution3.py b/product_of_array_except_self/solution3.py new file mode 100644 index 0000000..362a859 --- /dev/null +++ b/product_of_array_except_self/solution3.py @@ -0,0 +1,50 @@ +""" +Given an array of n integers where n > 1, nums, return an array output such +that output[i] is equal to the product of all the elements of nums except +nums[i]. + +Solve it without division and in O(n). + +For example, given [1,2,3,4], return [24,12,8,6]. + +Follow up: +Could you solve it with constant space complexity? (Note: The output array +does not count as extra space for the purpose of space complexity analysis.) +""" + +class Solution(object): + def productExceptSelf(self, nums): + """ + :type nums: List[int] + :rtype: List[int] + Space: O(n) + """ + n = len(nums) + # left[i] is the product to the left of i (nums[0..i - 1]) + left = [1 for i in range(n)] + # right[i] is the product to the right of i (nums[i + 1..-1]) + right = [1 for i in range(n)] + for i in range(1, n): + # i ranges from 1 to n - 1 + # j ranges from n - 2 to 0 + j = n - 1 - i + left[i] = left[i - 1] * nums[i - 1] + right[j] = right[j + 1] * nums[j + 1] + res = [1 for i in range(n)] + for i in range(n): + res[i] = left[i] * right[i] + return res + + +a0 = [0, 0] +a1 = [1, 2, 3] +a2 = [2, 3, 4] +a3 = [1, 2, 3, 4] +a4 = [2, 3, 4, 5] + +s = Solution() +print(s.productExceptSelf(a0)) +print(s.productExceptSelf(a1)) +print(s.productExceptSelf(a2)) +print(s.productExceptSelf(a3)) +print(s.productExceptSelf(a4)) diff --git a/product_of_array_except_self/solution4.py b/product_of_array_except_self/solution4.py new file mode 100644 index 0000000..609beac --- /dev/null +++ b/product_of_array_except_self/solution4.py @@ -0,0 +1,49 @@ + +""" +Given an array of n integers where n > 1, nums, return an array output such +that output[i] is equal to the product of all the elements of nums except +nums[i]. + +Solve it without division and in O(n). + +For example, given [1,2,3,4], return [24,12,8,6]. + +Follow up: +Could you solve it with constant space complexity? (Note: The output array +does not count as extra space for the purpose of space complexity analysis.) +""" + +class Solution(object): + def productExceptSelf(self, nums): + """ + :type nums: List[int] + :rtype: List[int] + """ + n = len(nums) + res = [1 for i in range(n)] + # Scan from left to right + for i in range(1, n): + res[i] = res[i - 1] * nums[i - 1] + + # right_product is the product accumulated to the right + right_product = 1 + for i in range(1, n): + # j ranges from i - 2 to 0 + j = n - 1 - i + right_product *= nums[j + 1] + res[j] *= right_product + return res + + +a0 = [0, 0] +a1 = [1, 2, 3] +a2 = [2, 3, 4] +a3 = [1, 2, 3, 4] +a4 = [2, 3, 4, 5] + +s = Solution() +print(s.productExceptSelf(a0)) +print(s.productExceptSelf(a1)) +print(s.productExceptSelf(a2)) +print(s.productExceptSelf(a3)) +print(s.productExceptSelf(a4)) From 1ce37a790a8d69ee0afa24e010b1d6dc870a4940 Mon Sep 17 00:00:00 2001 From: Shichao An Date: Tue, 8 Sep 2015 21:22:55 -0700 Subject: [PATCH 21/35] Added problem subjects --- valid_palindrome/solution.py | 16 ++++++++++++++++ valid_parentheses/solution.py | 16 ++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/valid_palindrome/solution.py b/valid_palindrome/solution.py index 414fb84..8fcb76b 100644 --- a/valid_palindrome/solution.py +++ b/valid_palindrome/solution.py @@ -1,3 +1,19 @@ +""" +Given a string, determine if it is a palindrome, considering only alphanumeric +characters and ignoring cases. + +For example, +"A man, a plan, a canal: Panama" is a palindrome. +"race a car" is not a palindrome. + +Note: +Have you consider that the string might be empty? This is a good question to +ask during an interview. + +For the purpose of this problem, we define empty string as valid palindrome. +""" + + class Solution: # @param s, a string # @return a boolean diff --git a/valid_parentheses/solution.py b/valid_parentheses/solution.py index 36777e5..1efec92 100644 --- a/valid_parentheses/solution.py +++ b/valid_parentheses/solution.py @@ -1,6 +1,18 @@ -class Solution: - # @return a boolean +""" +Given a string containing just the characters '(', ')', '{', '}', '[' and ']', +determine if the input string is valid. + +The brackets must close in the correct order, "()" and "()[]{}" are all valid +but "(]" and "([)]" are not. +""" + + +class Solution(object): def isValid(self, s): + """ + :type s: str + :rtype: bool + """ pars = { ')': '(', ']': '[', From dd98c900890f42ef7677603c7bceeff839fbd614 Mon Sep 17 00:00:00 2001 From: Shichao An Date: Wed, 9 Sep 2015 01:22:31 -0700 Subject: [PATCH 22/35] Added more --- multiply_strings/solution.py | 40 ++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 multiply_strings/solution.py diff --git a/multiply_strings/solution.py b/multiply_strings/solution.py new file mode 100644 index 0000000..b1f33af --- /dev/null +++ b/multiply_strings/solution.py @@ -0,0 +1,40 @@ +""" +Given two numbers represented as strings, return multiplication of the numbers +as a string. + +Note: The numbers can be arbitrarily large and are non-negative. +""" + + +class Solution(object): + def multiply(self, num1, num2): + """ + :type num1: str + :type num2: str + :rtype: str + """ + a = num1[::-1] + b = num2[::-1] + n = len(a) + m = len(b) + res = ['0' for i in range(n + m)] + for i in range(n): + c = 0 + for j in range(m): + tmp = int(a[i]) * int(b[j]) + int(res[i + j]) + c + digit = tmp % 10 + res[i + j] = str(digit) + c = tmp / 10 + if c > 0: + res[m + i] = str(c) + res = ''.join(res[::-1]) + for i, d in enumerate(res): + if d != '0': + return res[i:] + else: + return '0' + +s = Solution() + +print s.multiply('2', '21') +print s.multiply('83', '3') From 868a7eea070a81c38291f6942e10d26f797c2b93 Mon Sep 17 00:00:00 2001 From: Shichao An Date: Wed, 9 Sep 2015 17:01:32 -0700 Subject: [PATCH 23/35] Added some --- add_binary/solution3.py | 46 ++++++++++++++++++++++++++++++++++++++ group_anagrams/solution.py | 41 +++++++++++++++++++++++++++++++++ lru_cache/solution.py | 13 +++++++++++ lru_cache/solution2.py | 44 +++++++++++++++++++++++++++--------- valid_anagram/solution.py | 14 ++++++++++++ 5 files changed, 148 insertions(+), 10 deletions(-) create mode 100644 add_binary/solution3.py create mode 100644 group_anagrams/solution.py diff --git a/add_binary/solution3.py b/add_binary/solution3.py new file mode 100644 index 0000000..2fa7fd5 --- /dev/null +++ b/add_binary/solution3.py @@ -0,0 +1,46 @@ +""" +Given two binary strings, return their sum (also a binary string). + +For example, +a = "11" +b = "1" +Return "100". +""" + +class Solution(object): + def addBinary(self, a, b): + """ + :type a: str + :type b: str + :rtype: str + """ + a = a[::-1] + b = b[::-1] + m = len(a) + n = len(b) + i = 0 + c = 0 + res = ['0' for k in range(max(m, n) + 1)] + while i < m or i < n or c > 0: + tmp = c + if i < m: + tmp += int(a[i]) + if i < n: + tmp += int(b[i]) + bit = tmp % 2 + c = tmp / 2 + res[i] = str(bit) + i += 1 + res = res[::-1] + for i, c in enumerate(res): + if c != '0': + res = res[i:] + break + else: + res = ['0'] + return ''.join(res) + + +s = Solution() +print s.addBinary('11', '1') +print s.addBinary('111', '0010') diff --git a/group_anagrams/solution.py b/group_anagrams/solution.py new file mode 100644 index 0000000..87d81ea --- /dev/null +++ b/group_anagrams/solution.py @@ -0,0 +1,41 @@ +""" +Given an array of strings, group anagrams together. + +For example, given: ["eat", "tea", "tan", "ate", "nat", "bat"], Return: + +[ + ["ate", "eat","tea"], + ["nat","tan"], + ["bat"] +] +Note: +For the return value, each inner list's elements must follow the lexicographic +order. +All inputs will be in lower-case. + +""" + +class Solution(object): + def groupAnagrams(self, strs): + """ + :type strs: List[str] + :rtype: List[List[str]] + """ + d = {} + res = [] + for s in strs: + k = self.make_key(s) + if k not in d: + d[k] = [s] + else: + d[k].append(s) + for k in d: + res.append(sorted(d[k])) + return res + + def make_key(self, s): + return ''.join(sorted(s)) + + +s = Solution() +print s.groupAnagrams(["eat", "tea", "tan", "ate", "nat", "bat"]) diff --git a/lru_cache/solution.py b/lru_cache/solution.py index 5f6cdd4..63c49d7 100644 --- a/lru_cache/solution.py +++ b/lru_cache/solution.py @@ -1,6 +1,19 @@ """ +Design and implement a data structure for Least Recently Used (LRU) cache. It +should support the following operations: get and set. + +get(key) - Get the value (will always be positive) of the key if the key +exists in the cache, otherwise return -1. + +set(key, value) - Set or insert the value if the key is not already present. +When the cache reached its capacity, it should invalidate the least recently +used item before inserting a new item. + + TLE """ + + class LRUCache: # @param capacity, an integer diff --git a/lru_cache/solution2.py b/lru_cache/solution2.py index 75354b1..ef8be35 100644 --- a/lru_cache/solution2.py +++ b/lru_cache/solution2.py @@ -1,24 +1,42 @@ -class LRUCache: +""" +Design and implement a data structure for Least Recently Used (LRU) cache. It +should support the following operations: get and set. - # @param capacity, an integer +get(key) - Get the value (will always be positive) of the key if the key +exists in the cache, otherwise return -1. + +set(key, value) - Set or insert the value if the key is not already present. +When the cache reached its capacity, it should invalidate the least recently +used item before inserting a new item. + +""" + + +class LRUCache(object): def __init__(self, capacity): + """ + :type capacity: int + """ self.capacity = capacity self.times = List() self.cache = {} - self.timestamp = 0 - # @return an integer def get(self, key): + """ + :rtype: int + """ if key in self.cache: node = self.cache[key] self.times.touch(node) return node.value return -1 - # @param key, an integer - # @param value, an integer - # @return nothing def set(self, key, value): + """ + :type key: int + :type value: int + :rtype: nothing + """ if key in self.cache: node = self.cache[key] node.value = value @@ -75,11 +93,17 @@ def touch(self, node): self.head = node def remove(self, node): - """Remove node""" + """Remove a node""" prev_node = node.prev + next_node = node.next + # If node is not the head node if prev_node is not None: - prev_node.next = None - self.tail = prev_node + prev_node.next = next_node + # If node is not the tail node + if next_node is not None: + next_node.prev = prev_node + else: + self.tail = prev_node else: self.head = None self.tail = None diff --git a/valid_anagram/solution.py b/valid_anagram/solution.py index 7857150..963e21d 100644 --- a/valid_anagram/solution.py +++ b/valid_anagram/solution.py @@ -1,3 +1,16 @@ +""" +Given two strings s and t, write a function to determine if t is an anagram of +s. + +For example, +s = "anagram", t = "nagaram", return true. +s = "rat", t = "car", return false. + +Note: +You may assume the string contains only lowercase alphabets. +""" + + class Solution: # @param {string} s # @param {string} t @@ -20,6 +33,7 @@ def isAnagram(self, s, t): return False return True + s = Solution() print(s.isAnagram("aacc", "ccac")) print(s.isAnagram("abcd", "bcda")) From 3a6ffe27bfe253361db2fdc68d4e503cf9ef2f93 Mon Sep 17 00:00:00 2001 From: Shichao An Date: Wed, 9 Sep 2015 18:28:07 -0700 Subject: [PATCH 24/35] Added --- kth_largest_element_in_an_array/solution.py | 2 + kth_largest_element_in_an_array/solution2.py | 50 +++++++++++++++++++ search_in_rotated_sorted_array/solution2.py | 41 +++++++++++++++ .../solution2.py | 44 ++++++++++++++++ 4 files changed, 137 insertions(+) create mode 100644 kth_largest_element_in_an_array/solution2.py create mode 100644 search_in_rotated_sorted_array/solution2.py create mode 100644 search_in_rotated_sorted_array_ii/solution2.py diff --git a/kth_largest_element_in_an_array/solution.py b/kth_largest_element_in_an_array/solution.py index 976ef92..4611119 100644 --- a/kth_largest_element_in_an_array/solution.py +++ b/kth_largest_element_in_an_array/solution.py @@ -8,6 +8,7 @@ Note: You may assume k is always valid, 1 <= k <= array's length """ + import heapq class Solution(object): @@ -25,6 +26,7 @@ def findKthLargest(self, nums, k): if i == k - 1: return e + a1 = [3, 2, 1, 5, 6, 4] s = Solution() res = s.findKthLargest(a1, 2) diff --git a/kth_largest_element_in_an_array/solution2.py b/kth_largest_element_in_an_array/solution2.py new file mode 100644 index 0000000..236538e --- /dev/null +++ b/kth_largest_element_in_an_array/solution2.py @@ -0,0 +1,50 @@ +""" +Find the kth largest element in an unsorted array. Note that it is the kth +largest element in the sorted order, not the kth distinct element. + +For example, +Given [3,2,1,5,6,4] and k = 2, return 5. + +Note: You may assume k is always valid, 1 <= k <= array's length. +""" + + +class Solution(object): + def findKthLargest(self, nums, k): + """ + :type nums: List[int] + :type k: int + :rtype: int + + Quickselect: O(n) + """ + left = 0 + right = len(nums) - 1 + while left <= right: + pivot = self.partition(nums, left, right) + # nums[pivot] is (pivot + 1)th largest, so + # if pivot == k - 1, it is kth largest. + if pivot == k - 1: + return nums[pivot] + elif pivot < k - 1: + left = pivot + 1 + else: + right = pivot - 1 + + def partition(self, nums, left, right): + """Partition the array so that larger elements are to the left""" + pivot = right + # i is from left to right - 1 + j = left + for i in range(left, right): + if nums[i] > nums[pivot]: + nums[i], nums[j] = nums[j], nums[i] + j += 1 + nums[j], nums[pivot] = nums[pivot], nums[j] + return j + + +s = Solution() +a = [3, 2, 1, 5, 6, 4] + +print s.findKthLargest(a, 2) diff --git a/search_in_rotated_sorted_array/solution2.py b/search_in_rotated_sorted_array/solution2.py new file mode 100644 index 0000000..6c292ca --- /dev/null +++ b/search_in_rotated_sorted_array/solution2.py @@ -0,0 +1,41 @@ +""" +Suppose a sorted array is rotated at some pivot unknown to you beforehand. + +(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). + +You are given a target value to search. If found in the array return its +index, otherwise return -1. + +You may assume no duplicate exists in the array. +""" + +class Solution(object): + def search(self, nums, target): + """ + :type nums: List[int] + :type target: int + :rtype: int + """ + left = 0 + right = len(nums) - 1 + while left + 1 < right: + mid = left + (right - left) / 2 + if target == nums[mid]: + return mid + # Right side is sorted + elif nums[mid] < nums[right]: + if nums[mid] <= target <= nums[right]: + left = mid + else: + right = mid + # Left side is sorted + else: + if nums[left] <= target <= nums[mid]: + right = mid + else: + left = mid + if nums[left] == target: + return left + elif nums[right] == target: + return right + return -1 diff --git a/search_in_rotated_sorted_array_ii/solution2.py b/search_in_rotated_sorted_array_ii/solution2.py new file mode 100644 index 0000000..5de8ea7 --- /dev/null +++ b/search_in_rotated_sorted_array_ii/solution2.py @@ -0,0 +1,44 @@ +""" +Suppose a sorted array is rotated at some pivot unknown to you beforehand. + +(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). + +Follow up for "Search in Rotated Sorted Array": + +What if duplicates are allowed? + +Would this affect the run-time complexity? How and why? + +Write a function to determine if a given target is in the array. +""" + +class Solution(object): + def search(self, nums, target): + """ + :type nums: List[int] + :type target: int + :rtype: bool + """ + left = 0 + right = len(nums) - 1 + while left + 1 < right: + mid = left + (right - left) / 2 + if target == nums[mid]: + return True + # Left part is sorted + elif nums[mid] > nums[right]: + if nums[left] <= target < nums[mid]: + right = mid + else: + left = mid + # Right part is sorted + elif nums[mid] < nums[right]: + if nums[mid] < target <= nums[right]: + left = mid + else: + right = mid + else: + right -= 1 + if nums[left] == target or nums[right] == target: + return True + return False From 59a728e96bfc746ed08eb9c07d823397e06a10b1 Mon Sep 17 00:00:00 2001 From: Shichao An Date: Thu, 10 Sep 2015 18:55:41 -0700 Subject: [PATCH 25/35] Fixed --- combinations/solution.py | 26 ++++++++++++++++++++++++-- permutations/solution.py | 26 +++++++++++++++++++------- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/combinations/solution.py b/combinations/solution.py index 49a8f92..08778da 100644 --- a/combinations/solution.py +++ b/combinations/solution.py @@ -1,6 +1,28 @@ -class Solution: - # @return a list of lists of integers +""" +Given two integers n and k, return all possible combinations of k numbers out +of 1 ... n. + +For example, +If n = 4 and k = 2, a solution is: + +[ + [2,4], + [3,4], + [2,3], + [1,2], + [1,3], + [1,4], +] +""" + + +class Solution(object): def combine(self, n, k): + """ + :type n: int + :type k: int + :rtype: List[List[int]] + """ a = range(1, n + 1) return self.combine_aux(a, k) diff --git a/permutations/solution.py b/permutations/solution.py index b452a95..6796420 100644 --- a/permutations/solution.py +++ b/permutations/solution.py @@ -1,13 +1,25 @@ -class Solution: - # @param num, a list of integer - # @return a list of lists of integers - def permute(self, num): - if not num: +""" +Given a collection of numbers, return all possible permutations. + +For example, +[1,2,3] have the following permutations: +[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], and [3,2,1]. + +""" + + +class Solution(object): + def permute(self, nums): + """ + :type nums: List[int] + :rtype: List[List[int]] + """ + if not nums: return [[]] else: res = [] - for i, e in enumerate(num): - rest = num[:i] + num[i + 1:] + for i, e in enumerate(nums): + rest = nums[:i] + nums[i + 1:] rest_perms = self.permute(rest) for perm in rest_perms: perm.append(e) From fc20723097d49fff3f51abb1be72baced9bd9051 Mon Sep 17 00:00:00 2001 From: Shichao An Date: Fri, 11 Sep 2015 01:25:51 -0700 Subject: [PATCH 26/35] Added new problems --- clone_graph/solution.py | 43 ++++++++++++++++++++++++++++++++++++++++ clone_graph/solution2.py | 41 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 clone_graph/solution.py create mode 100644 clone_graph/solution2.py diff --git a/clone_graph/solution.py b/clone_graph/solution.py new file mode 100644 index 0000000..fc53774 --- /dev/null +++ b/clone_graph/solution.py @@ -0,0 +1,43 @@ +""" +Clone an undirected graph. Each node in the graph contains a label and a list +of its neighbors. +""" + +# Definition for a undirected graph node +# class UndirectedGraphNode(object): +# def __init__(self, x): +# self.label = x +# self.neighbors = [] + +class Solution(object): + def cloneGraph(self, node): + """ + :type node: UndirectedGraphNode + :rtype: UndirectedGraphNode + + BFS + """ + if node is None: + return None + queue = [] + start_cloned_node = UndirectedGraphNode(node.label) + visited = set() + # A dictionary that maps labels to cloned nodes + d = {node: start_cloned_node} + queue.append(node) + while queue: + node = queue.pop(0) + visited.add(node) + cloned_node = d[node] + cloned_neighbors = [] + for neighbor in node.neighbors: + if neighbor not in visited: + queue.append(neighbor) + if neighbor not in d: + cloned_neighbor = UndirectedGraphNode(neighbor.label) + d[neighbor] = cloned_neighbor + else: + cloned_neighbor = d[neighbor] + cloned_neighbors.append(cloned_neighbor) + cloned_node.neighbors = cloned_neighbors + return start_cloned_node diff --git a/clone_graph/solution2.py b/clone_graph/solution2.py new file mode 100644 index 0000000..ef2aa47 --- /dev/null +++ b/clone_graph/solution2.py @@ -0,0 +1,41 @@ +""" +Clone an undirected graph. Each node in the graph contains a label and a list +of its neighbors. +""" + +# Definition for a undirected graph node +# class UndirectedGraphNode(object): +# def __init__(self, x): +# self.label = x +# self.neighbors = [] + +class Solution(object): + def cloneGraph(self, node): + """ + :type node: UndirectedGraphNode + :rtype: UndirectedGraphNode + + DFS + """ + if node is None: + return None + self.visited = set() + cloned_node = UndirectedGraphNode(node.label) + self.d = {node: cloned_node} + self.visit(node) + return self.d[node] + + def visit(self, node): + if node not in self.visited: + self.visited.add(node) + cloned_node = self.d[node] + cloned_neighbors = [] + for neighbor in node.neighbors: + if neighbor not in self.d: + cloned_neighbor = UndirectedGraphNode(neighbor.label) + self.d[neighbor] = cloned_neighbor + else: + cloned_neighbor = self.d[neighbor] + cloned_neighbors.append(cloned_neighbor) + self.visit(neighbor) + cloned_node.neighbors = cloned_neighbors From f8034597c4057bbc7c49117e7bf99e83562918bb Mon Sep 17 00:00:00 2001 From: Shichao An Date: Tue, 15 Sep 2015 11:59:46 -0700 Subject: [PATCH 27/35] Added new problems --- delete_node_in_a_linked_list/solution.py | 25 +++++++++++ excel_sheet_column_number/solution.py | 42 +++++++++++++++++ first_bad_version/solution.py | 37 +++++++++++++++ invert_binary_tree/solution.py | 38 ++++++++++++++++ .../solution.py | 44 ++++++++++++++++++ number_of_1_bits/solution.py | 21 +++++++++ reverse_linked_list/solution.py | 45 +++++++++++++++++++ 7 files changed, 252 insertions(+) create mode 100644 delete_node_in_a_linked_list/solution.py create mode 100644 excel_sheet_column_number/solution.py create mode 100644 first_bad_version/solution.py create mode 100644 invert_binary_tree/solution.py create mode 100644 lowest_common_ancestor_of_a_binary_search_tree/solution.py create mode 100644 number_of_1_bits/solution.py create mode 100644 reverse_linked_list/solution.py diff --git a/delete_node_in_a_linked_list/solution.py b/delete_node_in_a_linked_list/solution.py new file mode 100644 index 0000000..10b4bd0 --- /dev/null +++ b/delete_node_in_a_linked_list/solution.py @@ -0,0 +1,25 @@ +""" +Write a function to delete a node (except the tail) in a singly linked list, +given only access to that node. + +Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third node +with value 3, the linked list should become 1 -> 2 -> 4 after calling your +function. +""" + + +# Definition for singly-linked list. +# class ListNode(object): +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution(object): + def deleteNode(self, node): + """ + :type node: ListNode + :rtype: void Do not return anything, modify node in-place instead. + """ + if node.next is not None: + node.val = node.next.val + node.next = node.next.next diff --git a/excel_sheet_column_number/solution.py b/excel_sheet_column_number/solution.py new file mode 100644 index 0000000..12b8eab --- /dev/null +++ b/excel_sheet_column_number/solution.py @@ -0,0 +1,42 @@ +""" +Related to question Excel Sheet Column Title + +Given a column title as appear in an Excel sheet, return its corresponding +column number. + +For example: + + A -> 1 + B -> 2 + C -> 3 + ... + Z -> 26 + AA -> 27 + AB -> 28 + AZ -> 26 + 26 = 52 + BA -> 52 + 1 = 53 +""" + +class Solution(object): + def titleToNumber(self, s): + """ + :type s: str + :rtype: int + """ + d = {} + res = 0 + for i, k in enumerate(range(ord('A'), ord('Z') + 1), start=1): + d[chr(k)] = i + j = 0 + for c in s[::-1]: + res += d[c] * (26 ** j) + j += 1 + return res + + +s = Solution() +print s.titleToNumber('A') +print s.titleToNumber('B') +print s.titleToNumber('AA') +print s.titleToNumber('BA') +print s.titleToNumber('AAA') diff --git a/first_bad_version/solution.py b/first_bad_version/solution.py new file mode 100644 index 0000000..e545d66 --- /dev/null +++ b/first_bad_version/solution.py @@ -0,0 +1,37 @@ +""" +You are a product manager and currently leading a team to develop a new +product. Unfortunately, the latest version of your product fails the quality +check. Since each version is developed based on the previous version, all the +versions after a bad version are also bad. + +Suppose you have n versions [1, 2, ..., n] and you want to find out the first +bad one, which causes all the following ones to be bad. + +You are given an API bool isBadVersion(version) which will return whether +version is bad. Implement a function to find the first bad version. You should +minimize the number of calls to the API. +""" + +# The isBadVersion API is already defined for you. +# @param version, an integer +# @return a bool +# def isBadVersion(version): + +class Solution(object): + def firstBadVersion(self, n): + """ + :type n: int + :rtype: int + """ + left = 1 + right = n + while left + 1 < right: + mid = left + (right - left) / 2 + if isBadVersion(mid): + right = mid + else: + left = mid + if isBadVersion(left): + return left + elif isBadVersion(right): + return right diff --git a/invert_binary_tree/solution.py b/invert_binary_tree/solution.py new file mode 100644 index 0000000..d85d53c --- /dev/null +++ b/invert_binary_tree/solution.py @@ -0,0 +1,38 @@ +""" +Invert a binary tree. + + 4 + / \ + 2 7 + / \ / \ +1 3 6 9 +to + 4 + / \ + 7 2 + / \ / \ +9 6 3 1 + +""" + +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def invertTree(self, root): + """ + :type root: TreeNode + :rtype: TreeNode + """ + if root is None: + return None + else: + left = self.invertTree(root.left) + right = self.invertTree(root.right) + root.left = right + root.right = left + return root diff --git a/lowest_common_ancestor_of_a_binary_search_tree/solution.py b/lowest_common_ancestor_of_a_binary_search_tree/solution.py new file mode 100644 index 0000000..f27dd2b --- /dev/null +++ b/lowest_common_ancestor_of_a_binary_search_tree/solution.py @@ -0,0 +1,44 @@ +""" +Given a binary search tree (BST), find the lowest common ancestor (LCA) of two +given nodes in the BST. + +According to the definition of LCA on Wikipedia: “The lowest common ancestor +is defined between two nodes v and w as the lowest node in T that has both v +and w as descendants (where we allow a node to be a descendant of itself).” + + _______6______ + / \ + ___2__ ___8__ + / \ / \ + 0 _4 7 9 + / \ + 3 5 +For example, the lowest common ancestor (LCA) of nodes 2 and 8 is 6. Another +example is LCA of nodes 2 and 4 is 2, since a node can be a descendant of +itself according to the LCA definition. +""" + +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def lowestCommonAncestor(self, root, p, q): + """ + :type root: TreeNode + :type p: TreeNode + :type q: TreeNode + :rtype: TreeNode + """ + if root is None: + return None + else: + if min(p.val, q.val) <= root.val <= max(p.val, q.val): + return root + elif root.val > max(p.val, q.val): + return self.lowestCommonAncestor(root.left, p, q) + else: + return self.lowestCommonAncestor(root.right, p, q) diff --git a/number_of_1_bits/solution.py b/number_of_1_bits/solution.py new file mode 100644 index 0000000..2823434 --- /dev/null +++ b/number_of_1_bits/solution.py @@ -0,0 +1,21 @@ +""" +Write a function that takes an unsigned integer and returns the number of ’1' +bits it has (also known as the Hamming weight). + +For example, the 32-bit integer ’11' has binary representation +00000000000000000000000000001011, so the function should return 3. + +""" + +class Solution(object): + def hammingWeight(self, n): + """ + :type n: int + :rtype: int + """ + res = 0 + while n > 0: + if n & 1 == 1: + res += 1 + n >>= 1 + return res diff --git a/reverse_linked_list/solution.py b/reverse_linked_list/solution.py new file mode 100644 index 0000000..c3231f8 --- /dev/null +++ b/reverse_linked_list/solution.py @@ -0,0 +1,45 @@ +""" +Reverse a singly linked list. + +click to show more hints. + +Hint: +A linked list can be reversed either iteratively or recursively. Could you +implement both? +""" + +# Definition for singly-linked list. +class ListNode(object): + def __init__(self, x): + self.val = x + self.next = None + + +class Solution(object): + def reverseList(self, head): + """ + :type head: ListNode + :rtype: ListNode + """ + res = None + while head is not None: + next_node = head.next + if res is None: + res = head + res.next = None + else: + # Insert to the head of `res` + head.next = res + res = head + head = next_node + return res + + +n1 = ListNode(1) +n2 = ListNode(2) +n1.next = n2 +s = Solution() +r1 = s.reverseList(n1) +print r1.val +print r1.next.val +print r1.next.next.val From 909537807045f93c92d7dae24c2ad9a9a6482c59 Mon Sep 17 00:00:00 2001 From: Shichao An Date: Tue, 15 Sep 2015 17:55:39 -0700 Subject: [PATCH 28/35] Added new problems and subjects --- 3sum/solution.py | 41 +++++++++++----- 3sum_closest/solution.py | 29 ++++++++--- 4sum/solution.py | 45 ++++++++++++----- add_binary/solution.py | 19 +++++-- add_binary/solution2.py | 19 +++++-- add_binary/solution3.py | 2 +- add_two_numbers/solution2.py | 19 +++++-- balanced_binary_tree/solution.py | 12 +++-- balanced_binary_tree/solution2.py | 12 +++-- best_time_to_buy_and_sell_stock/solution.py | 20 ++++++-- .../solution.py | 19 +++++-- .../solution.py | 21 ++++++-- binary_search_tree_iterator/solution.py | 5 +- binary_tree_inorder_traversal/solution.py | 27 ++++++++-- binary_tree_level_order_traversal/solution.py | 14 ++++-- .../solution2.py | 49 +++++++++++++++++++ .../solution.py | 12 +++-- binary_tree_paths/solution.py | 44 +++++++++++++++++ binary_tree_postorder_traversal/solution.py | 25 ++++++++-- binary_tree_preorder_traversal/solution.py | 27 ++++++++-- factorial_trailing_zeroes/solution.py | 18 +++++++ h_index/solution.py | 43 ++++++++++++++++ power_of_two/solution.py | 13 +++++ ugly_number/solution.py | 31 ++++++++++++ 24 files changed, 477 insertions(+), 89 deletions(-) create mode 100644 binary_tree_level_order_traversal/solution2.py create mode 100644 binary_tree_paths/solution.py create mode 100644 factorial_trailing_zeroes/solution.py create mode 100644 h_index/solution.py create mode 100644 power_of_two/solution.py create mode 100644 ugly_number/solution.py diff --git a/3sum/solution.py b/3sum/solution.py index da55b29..45a37c0 100644 --- a/3sum/solution.py +++ b/3sum/solution.py @@ -1,21 +1,40 @@ -class Solution: - # @return a list of lists of length 3, [[val1,val2,val3]] - def threeSum(self, num): - num.sort() +# -*- coding: utf-8 -*- +""" +Given an array S of n integers, are there elements a, b, c in S such that a + +b + c = 0? Find all unique triplets in the array which gives the sum of zero. + +Note: +Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c) +The solution set must not contain duplicate triplets. + For example, given array S = {-1 0 1 2 -1 -4}, + + A solution set is: + (-1, 0, 1) + (-1, -1, 2) +""" + + +class Solution(object): + def threeSum(self, nums): + """ + :type nums: List[int] + :rtype: List[List[int]] + """ + nums.sort() res = [] - for i in range(len(num) - 2): - if i == 0 or i > 0 and num[i - 1] != num[i]: + for i in range(len(nums) - 2): + if i == 0 or i > 0 and nums[i - 1] != nums[i]: left = i + 1 - right = len(num) - 1 + right = len(nums) - 1 while left < right: - s = num[i] + num[left] + num[right] + s = nums[i] + nums[left] + nums[right] if s == 0: - res.append([num[i], num[left], num[right]]) + res.append([nums[i], nums[left], nums[right]]) left += 1 right -= 1 - while left < right and num[left] == num[left - 1]: + while left < right and nums[left] == nums[left - 1]: left += 1 - while right > left and num[right] == num[right + 1]: + while right > left and nums[right] == nums[right + 1]: right -= 1 elif s < 0: left += 1 diff --git a/3sum_closest/solution.py b/3sum_closest/solution.py index 37800ab..e49b29f 100644 --- a/3sum_closest/solution.py +++ b/3sum_closest/solution.py @@ -1,14 +1,29 @@ -class Solution: - # @return an integer - def threeSumClosest(self, num, target): - num.sort() - n = len(num) - res = num[0] + num[1] + num[2] +""" +Given an array S of n integers, find three integers in S such that the sum is +closest to a given number, target. Return the sum of the three integers. You +may assume that each input would have exactly one solution. + + For example, given array S = {-1 2 1 -4}, and target = 1. + + The sum that is closest to the target is 2. (-1 + 2 + 1 = 2). +""" + + +class Solution(object): + def threeSumClosest(self, nums, target): + """ + :type nums: List[int] + :type target: int + :rtype: int + """ + nums.sort() + n = len(nums) + res = nums[0] + nums[1] + nums[2] for i in range(n - 2): l = i + 1 r = n - 1 while l < r: - s = num[i] + num[l] + num[r] + s = nums[i] + nums[l] + nums[r] if abs(s - target) < abs(res - target): res = s if s == target: diff --git a/4sum/solution.py b/4sum/solution.py index f1b2c2e..1ba43eb 100644 --- a/4sum/solution.py +++ b/4sum/solution.py @@ -1,27 +1,50 @@ +# -*- coding: utf-8 -*- # Time Limit Exceeded -class Solution: - # @return a list of lists of length 4, [[val1,val2,val3,val4]] - def fourSum(self, num, target): - n = len(num) - num.sort() +""" +Given an array S of n integers, are there elements a, b, c, and d in S such +that a + b + c + d = target? Find all unique quadruplets in the array which +gives the sum of target. + +Note: +Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b +≤ c ≤ d) +The solution set must not contain duplicate quadruplets. + For example, given array S = {1 0 -1 0 -2 2}, and target = 0. + + A solution set is: + (-1, 0, 0, 1) + (-2, -1, 1, 2) + (-2, 0, 0, 2) +""" + + +class Solution(object): + def fourSum(self, nums, target): + """ + :type nums: List[int] + :type target: int + :rtype: List[List[int]] + """ + n = len(nums) + nums.sort() res = [] for a in range(n - 3): - if a > 0 and num[a - 1] == num[a]: + if a > 0 and nums[a - 1] == nums[a]: continue for b in range(a + 1, n - 2): - if b > a + 1 and num[b - 1] == num[b]: + if b > a + 1 and nums[b - 1] == nums[b]: continue c = b + 1 d = n - 1 while c < d: - s = num[a] + num[b] + num[c] + num[d] + s = nums[a] + nums[b] + nums[c] + nums[d] if s == target: - res.append([num[a], num[b], num[c], num[d]]) + res.append([nums[a], nums[b], nums[c], nums[d]]) c += 1 d -= 1 - while c < d and num[c] == num[c - 1]: + while c < d and nums[c] == nums[c - 1]: c += 1 - while c < d and num[d] == num[d + 1]: + while c < d and nums[d] == nums[d + 1]: d -= 1 elif s < target: c += 1 diff --git a/add_binary/solution.py b/add_binary/solution.py index 919b178..baf1775 100644 --- a/add_binary/solution.py +++ b/add_binary/solution.py @@ -1,8 +1,19 @@ -class Solution: - # @param a, a string - # @param b, a string - # @return a string +""" +Given two binary strings, return their sum (also a binary string). + +For example, +a = "11" +b = "1" +Return "100". +""" + +class Solution(object): def addBinary(self, a, b): + """ + :type a: str + :type b: str + :rtype: str + """ res = [] # a is longer than b if len(a) < len(b): diff --git a/add_binary/solution2.py b/add_binary/solution2.py index 70dfe9f..19d69d1 100644 --- a/add_binary/solution2.py +++ b/add_binary/solution2.py @@ -1,8 +1,19 @@ -class Solution: - # @param a, a string - # @param b, a string - # @return a string +""" +Given two binary strings, return their sum (also a binary string). + +For example, +a = "11" +b = "1" +Return "100". +""" + +class Solution(object): def addBinary(self, a, b): + """ + :type a: str + :type b: str + :rtype: str + """ list_a = [int(i) for i in a[::-1]] list_b = [int(i) for i in b[::-1]] la = len(list_a) diff --git a/add_binary/solution3.py b/add_binary/solution3.py index 2fa7fd5..e212130 100644 --- a/add_binary/solution3.py +++ b/add_binary/solution3.py @@ -20,7 +20,7 @@ def addBinary(self, a, b): n = len(b) i = 0 c = 0 - res = ['0' for k in range(max(m, n) + 1)] + res = ['0' for _ in range(max(m, n) + 1)] while i < m or i < n or c > 0: tmp = c if i < m: diff --git a/add_two_numbers/solution2.py b/add_two_numbers/solution2.py index 9f82a85..bc9f4be 100644 --- a/add_two_numbers/solution2.py +++ b/add_two_numbers/solution2.py @@ -1,12 +1,25 @@ +""" +You are given two linked lists representing two non-negative numbers. The +digits are stored in reverse order and each of their nodes contain a single +digit. Add the two numbers and return it as a linked list. + +Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) +Output: 7 -> 0 -> 8 +""" + # Definition for singly-linked list. -# class ListNode: +# class ListNode(object): # def __init__(self, x): # self.val = x # self.next = None -class Solution: - # @return a ListNode +class Solution(object): def addTwoNumbers(self, l1, l2): + """ + :type l1: ListNode + :type l2: ListNode + :rtype: ListNode + """ carry = 0 res = None res_end = None diff --git a/balanced_binary_tree/solution.py b/balanced_binary_tree/solution.py index 9e80647..429c9a3 100644 --- a/balanced_binary_tree/solution.py +++ b/balanced_binary_tree/solution.py @@ -5,17 +5,19 @@ which the depth of the two subtrees of every node never differ by more than 1. """ -# Definition for a binary tree node -# class TreeNode: +# Definition for a binary tree node. +# class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = None -class Solution: - # @param root, a tree node - # @return a boolean +class Solution(object): def isBalanced(self, root): + """ + :type root: TreeNode + :rtype: bool + """ if root is None: return True else: diff --git a/balanced_binary_tree/solution2.py b/balanced_binary_tree/solution2.py index 1458e51..c09c7e2 100644 --- a/balanced_binary_tree/solution2.py +++ b/balanced_binary_tree/solution2.py @@ -5,17 +5,19 @@ which the depth of the two subtrees of every node never differ by more than 1. """ -# Definition for a binary tree node -# class TreeNode: +# Definition for a binary tree node. +# class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = None -class Solution: - # @param root, a tree node - # @return a boolean +class Solution(object): def isBalanced(self, root): + """ + :type root: TreeNode + :rtype: bool + """ if root is None: return True else: diff --git a/best_time_to_buy_and_sell_stock/solution.py b/best_time_to_buy_and_sell_stock/solution.py index 039732a..1541f62 100644 --- a/best_time_to_buy_and_sell_stock/solution.py +++ b/best_time_to_buy_and_sell_stock/solution.py @@ -1,12 +1,24 @@ -class Solution: - # @param prices, a list of integer - # @return an integer +""" +Say you have an array for which the ith element is the price of a given stock +on day i. + +If you were only permitted to complete at most one transaction (ie, buy one +and sell one share of the stock), design an algorithm to find the maximum +profit. +""" + + +class Solution(object): def maxProfit(self, prices): + """ + :type prices: List[int] + :rtype: int + """ if not prices: return 0 max_profit = 0 min_price = prices[0] - for i, p in enumerate(prices, start=0): + for i, p in enumerate(prices): max_profit = max(max_profit, (p - min_price)) min_price = min(min_price, p) return max_profit diff --git a/best_time_to_buy_and_sell_stock_ii/solution.py b/best_time_to_buy_and_sell_stock_ii/solution.py index 3183bf1..b6085e9 100644 --- a/best_time_to_buy_and_sell_stock_ii/solution.py +++ b/best_time_to_buy_and_sell_stock_ii/solution.py @@ -1,7 +1,20 @@ -class Solution: - # @param prices, a list of integer - # @return an integer +""" +Say you have an array for which the ith element is the price of a given stock +on day i. + +Design an algorithm to find the maximum profit. You may complete as many +transactions as you like (ie, buy one and sell one share of the stock multiple +times). However, you may not engage in multiple transactions at the +same time (ie, you must sell the stock before you buy again). +""" + + +class Solution(object): def maxProfit(self, prices): + """ + :type prices: List[int] + :rtype: int + """ if not prices: return 0 max_profit = 0 diff --git a/best_time_to_buy_and_sell_stock_iii/solution.py b/best_time_to_buy_and_sell_stock_iii/solution.py index 1b9e83a..0f99b37 100644 --- a/best_time_to_buy_and_sell_stock_iii/solution.py +++ b/best_time_to_buy_and_sell_stock_iii/solution.py @@ -1,7 +1,22 @@ -class Solution: - # @param prices, a list of integer - # @return an integer +""" +Say you have an array for which the ith element is the price of a given stock +on day i. + +Design an algorithm to find the maximum profit. You may complete at most two +transactions. + +Note: +You may not engage in multiple transactions at the same time (ie, you must +sell the stock before you buy again). +""" + + +class Solution(object): def maxProfit(self, prices): + """ + :type prices: List[int] + :rtype: int + """ if not prices: return 0 n = len(prices) diff --git a/binary_search_tree_iterator/solution.py b/binary_search_tree_iterator/solution.py index 22d09fe..46b30c9 100644 --- a/binary_search_tree_iterator/solution.py +++ b/binary_search_tree_iterator/solution.py @@ -1,12 +1,11 @@ # Definition for a binary tree node -# class TreeNode: +# class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = None -class BSTIterator: - # @param root, a binary search tree's root node +class BSTIterator(object): def __init__(self, root): self._arr = [] self._inorder(root) diff --git a/binary_tree_inorder_traversal/solution.py b/binary_tree_inorder_traversal/solution.py index 1c484ff..89f113f 100644 --- a/binary_tree_inorder_traversal/solution.py +++ b/binary_tree_inorder_traversal/solution.py @@ -1,14 +1,31 @@ -# Definition for a binary tree node -# class TreeNode: +""" +Given a binary tree, return the inorder traversal of its nodes' values. + +For example: +Given binary tree {1,#,2,3}, + 1 + \ + 2 + / + 3 +return [1,3,2]. + +Note: Recursive solution is trivial, could you do it iteratively? +""" + +# Definition for a binary tree node. +# class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = None -class Solution: - # @param root, a tree node - # @return a list of integers +class Solution(object): def inorderTraversal(self, root): + """ + :type root: TreeNode + :rtype: List[int] + """ path = [] if root is None: return path diff --git a/binary_tree_level_order_traversal/solution.py b/binary_tree_level_order_traversal/solution.py index a92f2c3..ec79035 100644 --- a/binary_tree_level_order_traversal/solution.py +++ b/binary_tree_level_order_traversal/solution.py @@ -16,17 +16,21 @@ [15,7] ] """ -# Definition for a binary tree node -# class TreeNode: + +# Definition for a binary tree node. +# class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = None -class Solution: - # @param root, a tree node - # @return a list of lists of integers +class Solution(object): def levelOrder(self, root): + """ + :type root: TreeNode + :rtype: List[List[int]] + """ + res = [] if root is None: return res diff --git a/binary_tree_level_order_traversal/solution2.py b/binary_tree_level_order_traversal/solution2.py new file mode 100644 index 0000000..0757f31 --- /dev/null +++ b/binary_tree_level_order_traversal/solution2.py @@ -0,0 +1,49 @@ +""" +Given a binary tree, return the level order traversal of its nodes' values. +(ie, from left to right, level by level). + +For example: +Given binary tree {3,9,20,#,#,15,7}, + 3 + / \ + 9 20 + / \ + 15 7 +return its level order traversal as: +[ + [3], + [9,20], + [15,7] +] +""" + +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def levelOrder(self, root): + """ + :type root: TreeNode + :rtype: List[List[int]] + """ + res = [] + if root is None: + return res + queue = [] + queue.append(root) + while queue: + n = len(queue) + level = [] + for i in range(n): + root = queue.pop(0) + if root.left is not None: + queue.append(root.left) + if root.right is not None: + queue.append(root.right) + level.append(root.val) + res.append(level[:]) + return res diff --git a/binary_tree_level_order_traversal_ii/solution.py b/binary_tree_level_order_traversal_ii/solution.py index 77042c0..7e191a3 100644 --- a/binary_tree_level_order_traversal_ii/solution.py +++ b/binary_tree_level_order_traversal_ii/solution.py @@ -17,17 +17,19 @@ ] """ -# Definition for a binary tree node -# class TreeNode: +# Definition for a binary tree node. +# class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = None -class Solution: - # @param root, a tree node - # @return a list of lists of integers +class Solution(object): def levelOrderBottom(self, root): + """ + :type root: TreeNode + :rtype: List[List[int]] + """ stack = [] if root is None: return stack diff --git a/binary_tree_paths/solution.py b/binary_tree_paths/solution.py new file mode 100644 index 0000000..e2db1ab --- /dev/null +++ b/binary_tree_paths/solution.py @@ -0,0 +1,44 @@ +""" +Given a binary tree, return all root-to-leaf paths. + +For example, given the following binary tree: + + 1 + / \ +2 3 + \ + 5 +All root-to-leaf paths are: + +["1->2->5", "1->3"] +""" + +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def binaryTreePaths(self, root): + """ + :type root: TreeNode + :rtype: List[str] + """ + res = [] + cand = [] + self.binary_tree_paths(root, cand, res) + return res + + def binary_tree_paths(self, root, cand, res): + if root is None: + return + else: + cand.append(root.val) + if root.left is None and root.right is None: + p = '->'.join(map(str, cand)) + res.append(p) + self.binary_tree_paths(root.left, cand, res) + self.binary_tree_paths(root.right, cand, res) + cand.pop() diff --git a/binary_tree_postorder_traversal/solution.py b/binary_tree_postorder_traversal/solution.py index 9460a4d..1ac5abc 100644 --- a/binary_tree_postorder_traversal/solution.py +++ b/binary_tree_postorder_traversal/solution.py @@ -1,14 +1,29 @@ -# Definition for a binary tree node -# class TreeNode: +""" +Given a binary tree, return the postorder traversal of its nodes' values. + +For example: +Given binary tree {1,#,2,3}, + 1 + \ + 2 + / + 3 +return [3,2,1]. +""" + +# Definition for a binary tree node. +# class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = None -class Solution: - # @param root, a tree node - # @return a list of integers +class Solution(object): def postorderTraversal(self, root): + """ + :type root: TreeNode + :rtype: List[int] + """ path = [] if root is None: return path diff --git a/binary_tree_preorder_traversal/solution.py b/binary_tree_preorder_traversal/solution.py index 749c70c..764ac39 100644 --- a/binary_tree_preorder_traversal/solution.py +++ b/binary_tree_preorder_traversal/solution.py @@ -1,14 +1,31 @@ -# Definition for a binary tree node -# class TreeNode: +""" +Given a binary tree, return the preorder traversal of its nodes' values. + +For example: +Given binary tree {1,#,2,3}, + 1 + \ + 2 + / + 3 + +return [1,2,3]. + +""" + +# Definition for a binary tree node. +# class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = None -class Solution: - # @param root, a tree node - # @return a list of integers +class Solution(object): def preorderTraversal(self, root): + """ + :type root: TreeNode + :rtype: List[int] + """ path = [] if root is None: return path diff --git a/factorial_trailing_zeroes/solution.py b/factorial_trailing_zeroes/solution.py new file mode 100644 index 0000000..f464e7b --- /dev/null +++ b/factorial_trailing_zeroes/solution.py @@ -0,0 +1,18 @@ +""" +Given an integer n, return the number of trailing zeroes in n!. + +Note: Your solution should be in logarithmic time complexity. +""" + +class Solution(object): + def trailingZeroes(self, n): + """ + :type n: int + :rtype: int + """ + res = 0 + i = 5 + while n / i >= 1: + res += n / i + i *= 5 + return res diff --git a/h_index/solution.py b/h_index/solution.py new file mode 100644 index 0000000..c059188 --- /dev/null +++ b/h_index/solution.py @@ -0,0 +1,43 @@ +""" +Given an array of citations (each citation is a non-negative integer) of a +researcher, write a function to compute the researcher's h-index. + +According to the definition of h-index on Wikipedia: "A scientist has index h +if h of his/her N papers have at least h citations each, and the other N - h +papers have no more than h citations each." + +For example, given citations = [3, 0, 6, 1, 5], which means the researcher has +5 papers in total and each of them had received 3, 0, 6, 1, 5 citations +respectively. Since the researcher has 3 papers with at least 3 citations each +and the remaining two with no more than 3 citations each, his h-index is 3. + +Note: If there are several possible values for h, the maximum one is taken as +the h-index. + +[6, 5, 3, 1, 0] +""" + + +class Solution(object): + def hIndex(self, citations): + """ + :type citations: List[int] + :rtype: int + """ + citations.sort(reverse=True) + count = 0 + lowest = 0 + h = 0 + for i, c in enumerate(citations): + lowest = c + count = i + 1 + if lowest >= count: + h = count + else: + break + return h + + +a1 = [3, 0, 6, 1, 5] +s = Solution() +print s.hIndex(a1) diff --git a/power_of_two/solution.py b/power_of_two/solution.py new file mode 100644 index 0000000..c83c010 --- /dev/null +++ b/power_of_two/solution.py @@ -0,0 +1,13 @@ +""" +Given an integer, write a function to determine if it is a power of two. +""" + +class Solution(object): + def isPowerOfTwo(self, n): + """ + :type n: int + :rtype: bool + """ + if n < 1: + return False + return n & (n - 1) == 0 diff --git a/ugly_number/solution.py b/ugly_number/solution.py new file mode 100644 index 0000000..157220d --- /dev/null +++ b/ugly_number/solution.py @@ -0,0 +1,31 @@ +""" +Write a program to check whether a given number is an ugly number. + +Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. +For example, 6, 8 are ugly while 14 is not ugly since it includes another +prime factor 7. + +Note that 1 is typically treated as an ugly number. +""" + +class Solution(object): + def isUgly(self, num): + """ + :type num: int + :rtype: bool + """ + if num == 0: + return False + factors = [2, 3, 5] + for factor in factors: + while num % factor == 0: + num /= factor + if num == 1: + return True + return False + + +s = Solution() +print s.isUgly(10) +print s.isUgly(6) +print s.isUgly(14) From 7a234e1036a417b78d4317c50065b1adcf6e9d29 Mon Sep 17 00:00:00 2001 From: Shichao An Date: Sun, 20 Sep 2015 02:26:29 -0700 Subject: [PATCH 29/35] Added alternative solutions --- majority_element/solution2.py | 25 ++++++++++++++++ majority_element_ii/solution.py | 51 +++++++++++++++++++++++++++++++++ maximum_subarray/solution3.py | 40 ++++++++++++++++++++++++++ single_number_ii/solution2.py | 39 +++++++++++++++++++++++++ 4 files changed, 155 insertions(+) create mode 100644 majority_element/solution2.py create mode 100644 majority_element_ii/solution.py create mode 100644 maximum_subarray/solution3.py create mode 100644 single_number_ii/solution2.py diff --git a/majority_element/solution2.py b/majority_element/solution2.py new file mode 100644 index 0000000..b083a97 --- /dev/null +++ b/majority_element/solution2.py @@ -0,0 +1,25 @@ +""" +Given an array of size n, find the majority element. The majority element is +the element that appears more than ⌊ n/2 ⌋ times. + +You may assume that the array is non-empty and the majority element always +exist in the array. +""" + +class Solution(object): + def majorityElement(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + count = 0 + cand = None + for c in nums: + if count == 0: + cand = c + count += 1 + elif cand == c: + count += 1 + else: + count -= 1 + return cand diff --git a/majority_element_ii/solution.py b/majority_element_ii/solution.py new file mode 100644 index 0000000..7363baf --- /dev/null +++ b/majority_element_ii/solution.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +""" +Given an integer array of size n, find all elements that appear more than ⌊ +n/3 ⌋ times. The algorithm should run in linear time and in O(1) space. +""" + +class Solution(object): + def majorityElement(self, nums): + """ + :type nums: List[int] + :rtype: List[int] + """ + cand1 = None + cand2 = None + count1 = 0 + count2 = 0 + for c in nums: + if cand1 == c: + count1 += 1 + elif cand2 == c: + count2 += 1 + elif count1 == 0: + cand1 = c + count1 += 1 + elif count2 == 0: + cand2 = c + count2 += 1 + else: + count1 -= 1 + count2 -= 1 + count1 = 0 + count2 = 0 + for c in nums: + if cand1 == c: + count1 += 1 + elif cand2 == c: + count2 += 1 + m = len(nums) / 3 + res = [] + if count1 > m: + res.append(cand1) + if count2 > m: + res.append(cand2) + return res + + +a1 = [8, 8, 7, 7, 7] +a2 = [1, 2] +s = Solution() +print s.majorityElement(a1) +print s.majorityElement(a2) diff --git a/maximum_subarray/solution3.py b/maximum_subarray/solution3.py new file mode 100644 index 0000000..a1183a4 --- /dev/null +++ b/maximum_subarray/solution3.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +""" +Find the contiguous subarray within an array (containing at least one number) +which has the largest sum. + +For example, given the array [−2,1,−3,4,−1,2,1,−5,4], +the contiguous subarray [4,−1,2,1] has the largest sum = 6. +""" + + +class Solution(object): + def maxSubArray(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + # s[i] is sum of nums[0]..nums[i] + # s[i] - s[j] is the sum of nums[j + 1] .. nums[i] + s = [0 for _ in nums] + ts = 0 # temporary sum + for i, c in enumerate(nums): + ts += c + s[i] = ts + min_sum = 0 + res = 0 + for i, c in enumerate(s): + res = max(res, c - min_sum) + min_sum = min(min_sum, c) + if res == 0: + return max(nums) + return res + + +a1 = [-2, 1, -3, 4, -1, 2, 1, -5, 4] +a2 = [-1, -2, -3, -1] +a3 = [1, 2] +s = Solution() +print s.maxSubArray(a1) +print s.maxSubArray(a2) +print s.maxSubArray(a3) diff --git a/single_number_ii/solution2.py b/single_number_ii/solution2.py new file mode 100644 index 0000000..080521a --- /dev/null +++ b/single_number_ii/solution2.py @@ -0,0 +1,39 @@ +""" +Given an array of integers, every element appears three times except for one. +Find that single one. + +Note: +Your algorithm should have a linear runtime complexity. Could you implement it +without using extra memory? +""" + + +class Solution(object): + def singleNumber(self, nums): + """ + :type nums: List[int] + :rtype: int + + Not correct on LeetCode + """ + # An 32-bit integer has at most 20 bits as base-3 + m = 20 + pow3 = [1 for _ in range(m)] + for i in range(1, m): + pow3[i] = pow3[i - 1] * 3 + print pow3 + + bits = [0 for _ in range(m)] + # For each bit of every integer, do XOR on three elements + for i in range(m): + for c in nums: + bits[i] = (bits[i] + c / pow3[i]) % 3 + res = 0 + for i in range(m): + res += pow3[i] * bits[i] + return res + + +a1 = [2, 2, 3, 2] +s = Solution() +print s.singleNumber(a1) From 8fd4ba83c8f71d299d121a9828c399c215560424 Mon Sep 17 00:00:00 2001 From: Shichao An Date: Mon, 21 Sep 2015 19:26:18 -0700 Subject: [PATCH 30/35] Added and fixed problems --- climbing_stairs/solution.py | 8 +- climbing_stairs/solution2.py | 8 +- implement_queue_using_stacks/solution.py | 64 ++++++++++++++++ implement_stack_using_queues/solution.py | 76 +++++++++++++++++++ implement_stack_using_queues/solution2.py | 72 ++++++++++++++++++ merge_two_sorted_lists/solution.py | 18 ++++- merge_two_sorted_lists/solution2.py | 36 +++++++++ move_zeroes/solution.py | 30 ++++++++ .../solution.py | 22 ++++-- .../solution.py | 51 ++++++++----- .../solution2.py | 45 +++++++++++ remove_element/solution.py | 18 +++-- reverse_linked_list/solution.py | 3 + reverse_linked_list/solution2.py | 49 ++++++++++++ roman_to_integer/solution.py | 14 +++- rotate_array/solution.py | 10 ++- same_tree/solution.py | 29 +++++++ symmetric_tree/solution.py | 31 ++++++-- valid_anagram/solution.py | 10 ++- 19 files changed, 537 insertions(+), 57 deletions(-) create mode 100644 implement_queue_using_stacks/solution.py create mode 100644 implement_stack_using_queues/solution.py create mode 100644 implement_stack_using_queues/solution2.py create mode 100644 merge_two_sorted_lists/solution2.py create mode 100644 move_zeroes/solution.py create mode 100644 remove_duplicates_from_sorted_list_ii/solution2.py create mode 100644 reverse_linked_list/solution2.py create mode 100644 same_tree/solution.py diff --git a/climbing_stairs/solution.py b/climbing_stairs/solution.py index 1bb0938..68e7093 100644 --- a/climbing_stairs/solution.py +++ b/climbing_stairs/solution.py @@ -5,10 +5,12 @@ climb to the top? """ -class Solution: - # @param n, an integer - # @return an integer +class Solution(object): def climbStairs(self, n): + """ + :type n: int + :rtype: int + """ if n == 0: return 1 t = [0] * (n + 1) diff --git a/climbing_stairs/solution2.py b/climbing_stairs/solution2.py index 8452c0b..5fb5560 100644 --- a/climbing_stairs/solution2.py +++ b/climbing_stairs/solution2.py @@ -5,10 +5,12 @@ climb to the top? """ -class Solution: - # @param n, an integer - # @return an integer +class Solution(object): def climbStairs(self, n): + """ + :type n: int + :rtype: int + """ t = [0 for i in range(n + 1)] return self.climb(n, t) diff --git a/implement_queue_using_stacks/solution.py b/implement_queue_using_stacks/solution.py new file mode 100644 index 0000000..d90dd58 --- /dev/null +++ b/implement_queue_using_stacks/solution.py @@ -0,0 +1,64 @@ +""" +Implement the following operations of a queue using stacks. + +push(x) -- Push element x to the back of queue. +pop() -- Removes the element from in front of queue. +peek() -- Get the front element. +empty() -- Return whether the queue is empty. + +Notes: +* You must use only standard operations of a stack -- which means only push to +top, peek/pop from top, size, and is empty operations are valid. +* Depending on your language, stack may not be supported natively. You may +simulate a stack by using a list or deque (double-ended queue), as long as you +use only standard operations of a stack. +* You may assume that all operations are valid (for example, no pop or peek +operations will be called on an empty queue). +""" + +class Queue(object): + def __init__(self): + """ + initialize your data structure here. + """ + self.stack1 = [] # Push + self.stack2 = [] # Pop + + def push(self, x): + """ + :type x: int + :rtype: nothing + """ + self.stack1.append(x) + + def pop(self): + """ + :rtype: nothing + """ + if not self.stack2: + self._move() + self.stack2.pop() + + def peek(self): + """ + :rtype: int + """ + if not self.stack2: + self._move() + return self.stack2[-1] + + def empty(self): + """ + :rtype: bool + """ + if not self.stack2: + self._move() + if not self.stack2: + return True + else: + return False + + def _move(self): + """Move elements from stack1 to stack2""" + while self.stack1: + self.stack2.append(self.stack1.pop()) diff --git a/implement_stack_using_queues/solution.py b/implement_stack_using_queues/solution.py new file mode 100644 index 0000000..590ebab --- /dev/null +++ b/implement_stack_using_queues/solution.py @@ -0,0 +1,76 @@ +""" +Implement the following operations of a stack using queues. + +push(x) -- Push element x onto stack. +pop() -- Removes the element on top of the stack. +top() -- Get the top element. +empty() -- Return whether the stack is empty. + +Notes: + +You must use only standard operations of a queue -- which means only push to +back, peek/pop from front, size, and is empty operations are valid. + +Depending on your language, queue may not be supported natively. You may +simulate a queue by using a list or deque (double-ended queue), as long as you +use only standard operations of a queue. + +You may assume that all operations are valid (for example, no pop or top +operations will be called on an empty stack). +""" + +class Stack(object): + def __init__(self): + """ + initialize your data structure here. + push(x) + 1. Enqueue x into queue1 + + pop() + 1. queue2 is initially empty, queue1 stores old elements: + queue2 = [] + queue1 = [a, b, c, x] + 2. Dequeue each elements except the last one from queue1 to queue2: + queue2 = [a, b, c] + queue1 = [x] + 3. Dequeue the last element of queue1, and store it as x: + x = x + queue2 = [a, b, c] + queue1 = [] + 4. Swap queue1 and queue2: + x = x + queue1 = [a, b, c] + queue2 = [] + 5. Return x + """ + self.queue1 = [] + self.queue2 = [] + + def push(self, x): + """ + :type x: int + :rtype: nothing + """ + self.queue1.append(x) + + def pop(self): + """ + :rtype: nothing + """ + while len(self.queue1) > 1: + self.queue2.append(self.queue1.pop(0)) + res = self.queue1.pop(0) + self.queue1, self.queue2 = self.queue2, self.queue1 + return res + + def top(self): + """ + :rtype: int + """ + return self.queue1[-1] + + def empty(self): + """ + :rtype: bool + """ + return not self.queue1 diff --git a/implement_stack_using_queues/solution2.py b/implement_stack_using_queues/solution2.py new file mode 100644 index 0000000..60cfa43 --- /dev/null +++ b/implement_stack_using_queues/solution2.py @@ -0,0 +1,72 @@ +""" +Implement the following operations of a stack using queues. + +push(x) -- Push element x onto stack. +pop() -- Removes the element on top of the stack. +top() -- Get the top element. +empty() -- Return whether the stack is empty. + +Notes: + +You must use only standard operations of a queue -- which means only push to +back, peek/pop from front, size, and is empty operations are valid. + +Depending on your language, queue may not be supported natively. You may +simulate a queue by using a list or deque (double-ended queue), as long as you +use only standard operations of a queue. + +You may assume that all operations are valid (for example, no pop or top +operations will be called on an empty stack). +""" + +class Stack(object): + def __init__(self): + """ + initialize your data structure here. + pop() + 1. Dequeue an element from queue1 + + push(x) + 1. queue2 is initially empty, queue1 stores old elements + queue2 = [] + queue1 = [a, b, c] + 2. enqueue(x) to queue2: + queue2 = [x] + queue1 = [a, b, c] + 3. dequeue() each element from queue1 to queue2: + queue2 = [x, a, b, c] + queue1 = [] + 4. Swap queue1 and queue2 + queue1 = [x, a, b, c] + queue2 = [] + """ + self.queue1 = [] + self.queue2 = [] + + def push(self, x): + """ + :type x: int + :rtype: nothing + """ + self.queue2.append(x) + while self.queue1: + self.queue2.append(self.queue1.pop(0)) + self.queue1, self.queue2 = self.queue2, self.queue1 + + def pop(self): + """ + :rtype: nothing + """ + return self.queue1.pop(0) + + def top(self): + """ + :rtype: int + """ + return self.queue1[0] + + def empty(self): + """ + :rtype: bool + """ + return not self.queue1 diff --git a/merge_two_sorted_lists/solution.py b/merge_two_sorted_lists/solution.py index 04e29a9..149a177 100644 --- a/merge_two_sorted_lists/solution.py +++ b/merge_two_sorted_lists/solution.py @@ -1,13 +1,23 @@ +""" +Merge two sorted linked lists and return it as a new list. The new list should +be made by splicing together the nodes of the first two lists. +""" + # Definition for singly-linked list. -# class ListNode: +# class ListNode(object): # def __init__(self, x): # self.val = x # self.next = None -class Solution: - # @param two ListNodes - # @return a ListNode +class Solution(object): def mergeTwoLists(self, l1, l2): + """ + :type l1: ListNode + :type l2: ListNode + :rtype: ListNode + + No dummy node + """ res = None res_end = None while l1 is not None and l2 is not None: diff --git a/merge_two_sorted_lists/solution2.py b/merge_two_sorted_lists/solution2.py new file mode 100644 index 0000000..ffa4ab3 --- /dev/null +++ b/merge_two_sorted_lists/solution2.py @@ -0,0 +1,36 @@ +""" +Merge two sorted linked lists and return it as a new list. The new list should +be made by splicing together the nodes of the first two lists. +""" + +# Definition for singly-linked list. +class ListNode(object): + def __init__(self, x): + self.val = x + self.next = None + +class Solution(object): + def mergeTwoLists(self, l1, l2): + """ + :type l1: ListNode + :type l2: ListNode + :rtype: ListNode + + Dummy node + """ + dummy = ListNode(0) + dummy_end = dummy + + while l1 is not None and l2 is not None: + if l1.val < l2.val: + dummy_end.next = l1 + l1 = l1.next + else: + dummy_end.next = l2 + l2 = l2.next + dummy_end = dummy_end.next + if l1 is not None: + dummy_end.next = l1 + else: + dummy_end.next = l2 + return dummy.next diff --git a/move_zeroes/solution.py b/move_zeroes/solution.py new file mode 100644 index 0000000..d86b8c5 --- /dev/null +++ b/move_zeroes/solution.py @@ -0,0 +1,30 @@ +""" +Given an array nums, write a function to move all 0's to the end of it while +maintaining the relative order of the non-zero elements. + +For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums +should be [1, 3, 12, 0, 0]. + +Note: +You must do this in-place without making a copy of the array. +Minimize the total number of operations. +""" + + +class Solution(object): + def moveZeroes(self, nums): + """ + :type nums: List[int] + :rtype: void Do not return anything, modify nums in-place instead. + """ + j = 0 + for i, c in enumerate(nums): + if c != 0: + nums[i], nums[j] = nums[j], nums[i] + j += 1 + + +a1 = [0, 1, 0, 3, 12] +s = Solution() +s.moveZeroes(a1) +print a1 diff --git a/remove_duplicates_from_sorted_list/solution.py b/remove_duplicates_from_sorted_list/solution.py index 252de54..4a712e5 100644 --- a/remove_duplicates_from_sorted_list/solution.py +++ b/remove_duplicates_from_sorted_list/solution.py @@ -1,13 +1,24 @@ +""" +Given a sorted linked list, delete all duplicates such that each element +appear only once. + +For example, +Given 1->1->2, return 1->2. +Given 1->1->2->3->3, return 1->2->3. +""" + # Definition for singly-linked list. -# class ListNode: +# class ListNode(object): # def __init__(self, x): # self.val = x # self.next = None -class Solution: - # @param head, a ListNode - # @return a ListNode +class Solution(object): def deleteDuplicates(self, head): + """ + :type head: ListNode + :rtype: ListNode + """ if head is None: return None if head.next is None: @@ -18,8 +29,7 @@ def deleteDuplicates(self, head): next_node = current.next if current.val == last.val: last.next = next_node - # free(current) in C else: - last = last.next + last = current current = next_node return head diff --git a/remove_duplicates_from_sorted_list_ii/solution.py b/remove_duplicates_from_sorted_list_ii/solution.py index 6c302ef..d91904b 100644 --- a/remove_duplicates_from_sorted_list_ii/solution.py +++ b/remove_duplicates_from_sorted_list_ii/solution.py @@ -1,27 +1,40 @@ +""" +Given a sorted linked list, delete all nodes that have duplicate numbers, +leaving only distinct numbers from the original list. + +For example, +Given 1->2->3->3->4->4->5, return 1->2->5. +Given 1->1->1->2->3, return 2->3. + +""" + # Definition for singly-linked list. -# class ListNode: +# class ListNode(object): # def __init__(self, x): # self.val = x # self.next = None -class Solution: - # @param head, a ListNode - # @return a ListNode +class Solution(object): def deleteDuplicates(self, head): + """ + :type head: ListNode + :rtype: ListNode + """ d = {} - h = head - while head is not None: - if head.val not in d: - d[head.val] = 1 + current = head + while current is not None: + if current.val not in d: + d[current.val] = 1 else: - d[head.val] += 1 - head = head.next - res = ListNode(0) # Dummy head of result list - end = res # End of result list - while h is not None: - if d[h.val] == 1: - end.next = h - end = end.next - h = h.next - end.next = None - return res.next + d[current.val] += 1 + current = current.next + current = head + dummy = ListNode(0) + dummy_end = dummy + while current is not None: + if d[current.val] == 1: + dummy_end.next = current + dummy_end = current + current = current.next + dummy_end.next = None + return dummy.next diff --git a/remove_duplicates_from_sorted_list_ii/solution2.py b/remove_duplicates_from_sorted_list_ii/solution2.py new file mode 100644 index 0000000..ab3abd4 --- /dev/null +++ b/remove_duplicates_from_sorted_list_ii/solution2.py @@ -0,0 +1,45 @@ +""" +Given a sorted linked list, delete all nodes that have duplicate numbers, +leaving only distinct numbers from the original list. + +For example, +Given 1->2->3->3->4->4->5, return 1->2->5. +Given 1->1->1->2->3, return 2->3. + +""" + +# Definition for singly-linked list. +# class ListNode(object): +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution(object): + def deleteDuplicates(self, head): + """ + :type head: ListNode + :rtype: ListNode + """ + if head is None: + return None + current = head + last = None + count = 0 # Repeated count of `last` + dummy = ListNode(0) + dummy_end = dummy + while current is not None: + if last is not None: + if current.val == last.val: + count += 1 + else: + if count == 0: + dummy_end.next = last + dummy_end = last + count = 0 + last = current + current = current.next + if count == 0: + dummy_end.next = last + dummy_end = last + dummy_end.next = None + return dummy.next diff --git a/remove_element/solution.py b/remove_element/solution.py index 45c6de0..bf0a000 100644 --- a/remove_element/solution.py +++ b/remove_element/solution.py @@ -6,15 +6,17 @@ the new length. """ -class Solution: - # @param A a list of integers - # @param elem an integer, value need to be removed - # @return an integer - def removeElement(self, A, elem): - n = len(A) +class Solution(object): + def removeElement(self, nums, val): + """ + :type nums: List[int] + :type val: int + :rtype: int + """ + n = len(nums) j = 0 for i in range(n): - if A[i] != elem: - A[j] = A[i] + if nums[i] != val: + nums[j] = nums[i] j += 1 return j diff --git a/reverse_linked_list/solution.py b/reverse_linked_list/solution.py index c3231f8..eaeb12a 100644 --- a/reverse_linked_list/solution.py +++ b/reverse_linked_list/solution.py @@ -20,10 +20,13 @@ def reverseList(self, head): """ :type head: ListNode :rtype: ListNode + + Iterative """ res = None while head is not None: next_node = head.next + # First node encountered if res is None: res = head res.next = None diff --git a/reverse_linked_list/solution2.py b/reverse_linked_list/solution2.py new file mode 100644 index 0000000..99a41f1 --- /dev/null +++ b/reverse_linked_list/solution2.py @@ -0,0 +1,49 @@ +""" +Reverse a singly linked list. + +click to show more hints. + +Hint: +A linked list can be reversed either iteratively or recursively. Could you +implement both? +""" + +# Definition for singly-linked list. +class ListNode(object): + def __init__(self, x): + self.val = x + self.next = None + + +class Solution(object): + def reverseList(self, head): + """ + :type head: ListNode + :rtype: ListNode + + Recursive (Time Limit Exceeded) + """ + if head is None: + return None + else: + rev_rest = self.reverseList(head.next) + current = rev_rest + if current is None: + return head + while current and current.next is not None: + current = current.next + current.next = head + head.next = None + return rev_rest + + +n1 = ListNode(1) +n2 = ListNode(2) +n3 = ListNode(3) +n1.next = n2 +n2.next = n3 +s = Solution() +r1 = s.reverseList(n1) +print r1.val +print r1.next.val +print r1.next.next.val diff --git a/roman_to_integer/solution.py b/roman_to_integer/solution.py index 5f78ea6..9bab067 100644 --- a/roman_to_integer/solution.py +++ b/roman_to_integer/solution.py @@ -1,6 +1,16 @@ -class Solution: - # @return an integer +""" +Given a roman numeral, convert it to an integer. + +Input is guaranteed to be within the range from 1 to 3999. +""" + + +class Solution(object): def romanToInt(self, s): + """ + :type s: str + :rtype: int + """ roman = { 'I': 1, 'V': 5, diff --git a/rotate_array/solution.py b/rotate_array/solution.py index 4cc6d6f..344b78a 100644 --- a/rotate_array/solution.py +++ b/rotate_array/solution.py @@ -28,7 +28,11 @@ def reverse(self, nums, i, j): j -= 1 -a = [1, 2, 3, 4, 5, 6, 7] +a1 = [1, 2, 3, 4, 5, 6, 7] s = Solution() -s.rotate(a, 3) -print(a) +s.rotate(a1, 3) +print(a1) + +a2 = [1] +s.rotate(a2, 2) +print(a2) diff --git a/same_tree/solution.py b/same_tree/solution.py new file mode 100644 index 0000000..20e520a --- /dev/null +++ b/same_tree/solution.py @@ -0,0 +1,29 @@ +""" +Given two binary trees, write a function to check if they are equal or not. + +Two binary trees are considered equal if they are structurally identical and +the nodes have the same value. +""" + +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def isSameTree(self, p, q): + """ + :type p: TreeNode + :type q: TreeNode + :rtype: bool + """ + if p is None and q is None: + return True + elif p is not None and q is not None: + if (p.val == q.val and + self.isSameTree(p.left, q.left) and + self.isSameTree(p.right, q.right)): + return True + return False diff --git a/symmetric_tree/solution.py b/symmetric_tree/solution.py index 2a32b68..979ad45 100644 --- a/symmetric_tree/solution.py +++ b/symmetric_tree/solution.py @@ -1,14 +1,35 @@ -# Definition for a binary tree node -# class TreeNode: +""" +Given a binary tree, check whether it is a mirror of itself (ie, symmetric +around its center). + +For example, this binary tree is symmetric: + + 1 + / \ + 2 2 + / \ / \ +3 4 4 3 +But the following is not: + 1 + / \ + 2 2 + \ \ + 3 3 +""" + +# Definition for a binary tree node. +# class TreeNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = None -class Solution: - # @param root, a tree node - # @return a boolean +class Solution(object): def isSymmetric(self, root): + """ + :type root: TreeNode + :rtype: bool + """ if root is None: return True if root.left is None and root.right is None: diff --git a/valid_anagram/solution.py b/valid_anagram/solution.py index 963e21d..4c80cb6 100644 --- a/valid_anagram/solution.py +++ b/valid_anagram/solution.py @@ -11,11 +11,13 @@ """ -class Solution: - # @param {string} s - # @param {string} t - # @return {boolean} +class Solution(object): def isAnagram(self, s, t): + """ + :type s: str + :type t: str + :rtype: bool + """ if len(s) != len(t): return False d = {} From 219cc8f52413ea07f6a41ffa9015fd30a7e96699 Mon Sep 17 00:00:00 2001 From: Shichao An Date: Mon, 21 Sep 2015 21:35:08 -0700 Subject: [PATCH 31/35] Added --- clone_graph/solution3.py | 42 ++++++++++++++++++++++++++++++++++++ course_schedule/solution.py | 2 ++ course_schedule/solution2.py | 2 ++ 3 files changed, 46 insertions(+) create mode 100644 clone_graph/solution3.py diff --git a/clone_graph/solution3.py b/clone_graph/solution3.py new file mode 100644 index 0000000..d8918f5 --- /dev/null +++ b/clone_graph/solution3.py @@ -0,0 +1,42 @@ +""" +Clone an undirected graph. Each node in the graph contains a label and a list +of its neighbors. +""" + +# Definition for a undirected graph node +# class UndirectedGraphNode(object): +# def __init__(self, x): +# self.label = x +# self.neighbors = [] + +class Solution(object): + def cloneGraph(self, node): + """ + :type node: UndirectedGraphNode + :rtype: UndirectedGraphNode + BFS with only a queue and dictionary (used as visited set) + """ + if node is None: + return None + queue = [] + start_node = node + start_cloned_node = UndirectedGraphNode(node.label) + d = {node: start_cloned_node} + queue.append(node) + i = 0 + while i < len(queue): + node = queue[i] + i += 1 + for neighbor in node.neighbors: + if neighbor not in d: + queue.append(neighbor) + cloned_neighbor = UndirectedGraphNode(neighbor.label) + d[neighbor] = cloned_neighbor + for node in queue: + cloned_node = d[node] + cloned_neighbors = [] + for neighbor in node.neighbors: + cloned_neighbor = d[neighbor] + cloned_neighbors.append(cloned_neighbor) + cloned_node.neighbors = cloned_neighbors + return d[start_node] diff --git a/course_schedule/solution.py b/course_schedule/solution.py index 7bc89f8..e3830c0 100644 --- a/course_schedule/solution.py +++ b/course_schedule/solution.py @@ -25,6 +25,8 @@ def canFinish(self, numCourses, prerequisites): :type numCourses: int :type prerequisites: List[List[int]] :rtype: bool + + Topological sort """ # An implementation of # https://en.wikipedia.org/wiki/Topological_sorting#Algorithms diff --git a/course_schedule/solution2.py b/course_schedule/solution2.py index bcd9edc..6b27b42 100644 --- a/course_schedule/solution2.py +++ b/course_schedule/solution2.py @@ -28,6 +28,8 @@ def canFinish(self, numCourses, prerequisites): :type numCourses: int :type prerequisites: List[List[int]] :rtype: bool + + Detect if course prerequisites graph has a cycle. """ self.unvisited = set(range(numCourses)) From bdd034283389423ddfdc1e650d414922a4f93370 Mon Sep 17 00:00:00 2001 From: Shichao An Date: Tue, 22 Sep 2015 00:44:34 -0700 Subject: [PATCH 32/35] Fixed --- length_of_last_word/solution.py | 21 +++++++++++++--- length_of_last_word/solution2.py | 23 ++++++++++++++--- length_of_last_word/solution3.py | 30 +++++++++++++++++++++++ merge_sorted_array/solution.py | 35 +++++++++++++++++--------- merge_sorted_array/solution2.py | 37 ++++++++++++++++++++++++++++ pascals_triangle/solution.py | 23 +++++++++++++++-- pascals_triangle_ii/solution.py | 32 ++++++++++++++++++++---- plus_one/solution3.py | 42 ++++++++++++++++++++++++++++++++ rotate_array/solution.py | 1 + valid_sudoku/solution.py | 20 ++++++++++++--- 10 files changed, 236 insertions(+), 28 deletions(-) create mode 100644 length_of_last_word/solution3.py create mode 100644 merge_sorted_array/solution2.py create mode 100644 plus_one/solution3.py diff --git a/length_of_last_word/solution.py b/length_of_last_word/solution.py index bdc714c..939df1e 100644 --- a/length_of_last_word/solution.py +++ b/length_of_last_word/solution.py @@ -1,7 +1,22 @@ -class Solution: - # @param s, a string - # @return an integer +""" +Given a string s consists of upper/lower-case alphabets and empty space +characters ' ', return the length of last word in the string. + +If the last word does not exist, return 0. + +Note: A word is defined as a character sequence consists of non-space +characters only. + +For example, Given s = "Hello World", +return 5. +""" + +class Solution(object): def lengthOfLastWord(self, s): + """ + :type s: str + :rtype: int + """ n = len(s) i = n - 1 while i >= 0 and s[i].isspace(): diff --git a/length_of_last_word/solution2.py b/length_of_last_word/solution2.py index 4c11689..5d8c207 100644 --- a/length_of_last_word/solution2.py +++ b/length_of_last_word/solution2.py @@ -1,12 +1,27 @@ -class Solution: - # @param s, a string - # @return an integer +""" +Given a string s consists of upper/lower-case alphabets and empty space +characters ' ', return the length of last word in the string. + +If the last word does not exist, return 0. + +Note: A word is defined as a character sequence consists of non-space +characters only. + +For example, Given s = "Hello World", +return 5. +""" + +class Solution(object): def lengthOfLastWord(self, s): + """ + :type s: str + :rtype: int + """ n = len(s) p = n - 1 right = -1 while p >= 0: - if right == - 1 and s[p] != ' ': + if right == -1 and s[p] != ' ': right = p elif right >= 0 and s[p] == ' ': return right - p diff --git a/length_of_last_word/solution3.py b/length_of_last_word/solution3.py new file mode 100644 index 0000000..772576b --- /dev/null +++ b/length_of_last_word/solution3.py @@ -0,0 +1,30 @@ +""" +Given a string s consists of upper/lower-case alphabets and empty space +characters ' ', return the length of last word in the string. + +If the last word does not exist, return 0. + +Note: A word is defined as a character sequence consists of non-space +characters only. + +For example, Given s = "Hello World", +return 5. +""" + +class Solution(object): + def lengthOfLastWord(self, s): + """ + :type s: str + :rtype: int + """ + n = len(s) + i = n - 1 + res = 0 + while i >= 0: + if s[i] != ' ': + res += 1 + else: + if res != 0: + break + i -= 1 + return res diff --git a/merge_sorted_array/solution.py b/merge_sorted_array/solution.py index 8979053..cb353f7 100644 --- a/merge_sorted_array/solution.py +++ b/merge_sorted_array/solution.py @@ -1,22 +1,35 @@ -class Solution: - # @param A a list of integers - # @param m an integer, length of A - # @param B a list of integers - # @param n an integer, length of B - # @return nothing - def merge(self, A, m, B, n): +""" +Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one +sorted array. + +Note: +You may assume that nums1 has enough space (size that is greater or equal to m ++ n) to hold additional elements from nums2. The number of elements +initialized in nums1 and nums2 are m and n respectively. +""" + + +class Solution(object): + def merge(self, nums1, m, nums2, n): + """ + :type nums1: List[int] + :type m: int + :type nums2: List[int] + :type n: int + :rtype: void Do not return anything, modify nums1 in-place instead. + """ i = m - 1 j = n - 1 k = m + n - 1 while i >= 0 and j >= 0: - if A[i] > B[j]: - A[k] = A[i] + if nums1[i] > nums2[j]: + nums1[k] = nums1[i] i -= 1 else: - A[k] = B[j] + nums1[k] = nums2[j] j -= 1 k -= 1 while j >= 0: - A[k] = B[j] + nums1[k] = nums2[j] j -= 1 k -= 1 diff --git a/merge_sorted_array/solution2.py b/merge_sorted_array/solution2.py new file mode 100644 index 0000000..426c8b4 --- /dev/null +++ b/merge_sorted_array/solution2.py @@ -0,0 +1,37 @@ +""" +Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one +sorted array. + +Note: +You may assume that nums1 has enough space (size that is greater or equal to m ++ n) to hold additional elements from nums2. The number of elements +initialized in nums1 and nums2 are m and n respectively. +""" + + +class Solution(object): + def merge(self, nums1, m, nums2, n): + """ + :type nums1: List[int] + :type m: int + :type nums2: List[int] + :type n: int + :rtype: void Do not return anything, modify nums1 in-place instead. + """ + i = m - 1 + j = n - 1 + k = m + n - 1 + while k >= 0: + if i >= 0 and j >= 0: + if nums1[i] > nums2[j]: + nums1[k] = nums1[i] + i -= 1 + else: + nums1[k] = nums2[j] + j -= 1 + elif i < 0: + nums1[k] = nums2[j] + j -= 1 + else: + break + k -= 1 diff --git a/pascals_triangle/solution.py b/pascals_triangle/solution.py index 9c903e2..22faa49 100644 --- a/pascals_triangle/solution.py +++ b/pascals_triangle/solution.py @@ -1,6 +1,25 @@ -class Solution: - # @return a list of lists of integers +""" +Given numRows, generate the first numRows of Pascal's triangle. + +For example, given numRows = 5, +Return + +[ + [1], + [1,1], + [1,2,1], + [1,3,3,1], + [1,4,6,4,1] +] +""" + + +class Solution(object): def generate(self, numRows): + """ + :type numRows: int + :rtype: List[List[int]] + """ res = [] if numRows == 0: return res diff --git a/pascals_triangle_ii/solution.py b/pascals_triangle_ii/solution.py index bb1cbb2..1b9b6db 100644 --- a/pascals_triangle_ii/solution.py +++ b/pascals_triangle_ii/solution.py @@ -1,10 +1,32 @@ -class Solution: - # @return a list of integers +""" +Given an index k, return the kth row of the Pascal's triangle. + +For example, given k = 3, +Return [1,3,3,1]. + + +[1,1,1,1,1], +[1,1,1,1,1], +[1,2,1,1,1], +[1,3,3,1,1], +[1,4,6,4,1], + +Note: +Could you optimize your algorithm to use only O(k) extra space? +""" + +class Solution(object): def getRow(self, rowIndex): + """ + :type rowIndex: int + :rtype: List[int] + """ res = [1 for i in range(rowIndex + 1)] for row in range(rowIndex + 1): - for col in range(row + 1): + for col in range(1, row): col = row - col - if col < row and col > 0: - res[col] += res[col - 1] + res[col] += res[col - 1] return res + +s = Solution() +print s.getRow(3) diff --git a/plus_one/solution3.py b/plus_one/solution3.py new file mode 100644 index 0000000..a526fb6 --- /dev/null +++ b/plus_one/solution3.py @@ -0,0 +1,42 @@ +""" +Given a non-negative number represented as an array of digits, plus one to the +number. + +The digits are stored such that the most significant digit is at the head of +the list. +""" + +class Solution(object): + def plusOne(self, digits): + """ + :type digits: List[int] + :rtype: List[int] + """ + digits = digits[::-1] + n = len(digits) + temp = 0 + # Treat "plus one" as the initial carry being 1 + carry = 1 + i = 0 + res = [] + while i < n or carry > 0: + temp = 0 + if i < n: + temp += digits[i] + if carry > 0: + temp += carry + digit = temp % 10 + carry = temp / 10 + res.append(digit) + i += 1 + return res[::-1] + +a0 = [] +a1 = [3, 3, 5] +a2 = [4, 9, 9] +a3 = [9, 9, 9] +s = Solution() +print s.plusOne(a0) +print s.plusOne(a1) +print s.plusOne(a2) +print s.plusOne(a3) diff --git a/rotate_array/solution.py b/rotate_array/solution.py index 344b78a..1c1bbc3 100644 --- a/rotate_array/solution.py +++ b/rotate_array/solution.py @@ -17,6 +17,7 @@ def rotate(self, nums, k): :rtype: void Do not return anything, modify nums in-place instead. """ n = len(nums) + k = k % n self.reverse(nums, 0, n - 1) self.reverse(nums, 0, k - 1) self.reverse(nums, k, n - 1) diff --git a/valid_sudoku/solution.py b/valid_sudoku/solution.py index 58e8457..8ae8224 100644 --- a/valid_sudoku/solution.py +++ b/valid_sudoku/solution.py @@ -1,7 +1,21 @@ -class Solution: - # @param board, a 9x9 2D array - # @return a boolean +""" +Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules +(http://sudoku.com.au/TheRules.aspx). + +The Sudoku board could be partially filled, where empty cells are filled with +the character '.'. + +A valid Sudoku board (partially filled) is not necessarily solvable. Only the +filled cells need to be validated. + +""" + +class Solution(object): def isValidSudoku(self, board): + """ + :type board: List[List[str]] + :rtype: bool + """ # Check rows for i in range(9): d = {} From 89fd0484b878ea3dc2364a322bb357990fb5ee78 Mon Sep 17 00:00:00 2001 From: Shichao An Date: Tue, 22 Sep 2015 11:57:47 -0700 Subject: [PATCH 33/35] Added problem subjects --- count_and_say/solution.py | 21 +++++++++++++++++++-- implement_strstr/solution.py | 7 +++++++ implement_strstr/solution2.py | 10 ++++++++++ longest_common_prefix/solution.py | 13 +++++++++++-- permutations_ii/solution.py | 29 ++++++++++++++++++++--------- permutations_ii/solution2.py | 29 ++++++++++++++++++++--------- reverse_integer/solution.py | 14 ++++++++++++-- valid_palindrome/solution.py | 8 +++++--- 8 files changed, 104 insertions(+), 27 deletions(-) diff --git a/count_and_say/solution.py b/count_and_say/solution.py index 5d28e54..b0bf93b 100644 --- a/count_and_say/solution.py +++ b/count_and_say/solution.py @@ -1,6 +1,22 @@ -class Solution: - # @return a string +""" +The count-and-say sequence is the sequence of integers beginning as follows: +1, 11, 21, 1211, 111221, ... + +1 is read off as "one 1" or 11. +11 is read off as "two 1s" or 21. +21 is read off as "one 2, then one 1" or 1211. +Given an integer n, generate the nth sequence. + +Note: The sequence of integers will be represented as a string. +""" + + +class Solution(object): def countAndSay(self, n): + """ + :type n: int + :rtype: str + """ ln = list(str(1)) for i in range(1, n): tn = [] @@ -19,6 +35,7 @@ def countAndSay(self, n): ln = tn return ''.join(ln) + s = Solution() print s.countAndSay(1) print s.countAndSay(2) diff --git a/implement_strstr/solution.py b/implement_strstr/solution.py index 5be4391..24ec26a 100644 --- a/implement_strstr/solution.py +++ b/implement_strstr/solution.py @@ -1,3 +1,10 @@ +""" +Implement strStr(). + +Returns the index of the first occurrence of needle in haystack, or -1 if +needle is not part of haystack. +""" + class Solution(object): def strStr(self, haystack, needle): """ diff --git a/implement_strstr/solution2.py b/implement_strstr/solution2.py index 14ed87f..def8da0 100644 --- a/implement_strstr/solution2.py +++ b/implement_strstr/solution2.py @@ -1,9 +1,19 @@ +""" +Implement strStr(). + +Returns the index of the first occurrence of needle in haystack, or -1 if +needle is not part of haystack. +""" + class Solution(object): def strStr(self, haystack, needle): """ :type haystack: str :type needle: str :rtype: int + + needle: | n | + haystack: | n - m | m | """ n = len(haystack) m = len(needle) diff --git a/longest_common_prefix/solution.py b/longest_common_prefix/solution.py index a4b2867..3a62543 100644 --- a/longest_common_prefix/solution.py +++ b/longest_common_prefix/solution.py @@ -1,6 +1,15 @@ -class Solution: - # @return a string +""" +Write a function to find the longest common prefix string amongst an array of +strings. +""" + + +class Solution(object): def longestCommonPrefix(self, strs): + """ + :type strs: List[str] + :rtype: str + """ if not strs: return "" res = strs[0] diff --git a/permutations_ii/solution.py b/permutations_ii/solution.py index 325a8f7..d2d28fe 100644 --- a/permutations_ii/solution.py +++ b/permutations_ii/solution.py @@ -1,21 +1,32 @@ -class Solution: - # @param num, a list of integer - # @return a list of lists of integers - def permuteUnique(self, num): +""" +Given a collection of numbers that might contain duplicates, return all +possible unique permutations. + +For example, +[1,1,2] have the following unique permutations: +[1,1,2], [1,2,1], and [2,1,1]. +""" + +class Solution(object): + def permuteUnique(self, nums): + """ + :type nums: List[int] + :rtype: List[List[int]] + """ d = {} - return self.permute(num, d) + return self.permute(nums, d) - def permute(self, num, d): - if not num: + def permute(self, nums, d): + if not nums: return [[]] else: res = [] - for i, c in enumerate(num): + for i, c in enumerate(nums): if c in d: continue else: d[c] = True - rest_perms = self.permuteUnique(num[:i] + num[i + 1:]) + rest_perms = self.permuteUnique(nums[:i] + nums[i + 1:]) for perm in rest_perms: perm.insert(0, c) res += rest_perms diff --git a/permutations_ii/solution2.py b/permutations_ii/solution2.py index b8528e6..089ad1e 100644 --- a/permutations_ii/solution2.py +++ b/permutations_ii/solution2.py @@ -1,18 +1,29 @@ -class Solution: - # @param num, a list of integer - # @return a list of lists of integers - def permuteUnique(self, num): - return self.permute(sorted(num)) +""" +Given a collection of numbers that might contain duplicates, return all +possible unique permutations. - def permute(self, num): - if not num: +For example, +[1,1,2] have the following unique permutations: +[1,1,2], [1,2,1], and [2,1,1]. +""" + +class Solution(object): + def permuteUnique(self, nums): + """ + :type nums: List[int] + :rtype: List[List[int]] + """ + return self.permute(sorted(nums)) + + def permute(self, nums): + if not nums: return [[]] else: res = [] prev = None - for i, e in enumerate(num): + for i, e in enumerate(nums): if prev is None or prev != e: - rest = num[:i] + num[i + 1:] + rest = nums[:i] + nums[i + 1:] rest_perms = self.permute(rest) for perm in rest_perms: perm.append(e) diff --git a/reverse_integer/solution.py b/reverse_integer/solution.py index 5d4cfa4..b68df23 100644 --- a/reverse_integer/solution.py +++ b/reverse_integer/solution.py @@ -1,6 +1,16 @@ -class Solution: - # @return an integer +""" +Reverse digits of an integer. + +Example1: x = 123, return 321 +Example2: x = -123, return -321 +""" + +class Solution(object): def reverse(self, x): + """ + :type x: int + :rtype: int + """ pos = True if x < 0: pos = False diff --git a/valid_palindrome/solution.py b/valid_palindrome/solution.py index 8fcb76b..90488d4 100644 --- a/valid_palindrome/solution.py +++ b/valid_palindrome/solution.py @@ -14,10 +14,12 @@ """ -class Solution: - # @param s, a string - # @return a boolean +class Solution(object): def isPalindrome(self, s): + """ + :type s: str + :rtype: bool + """ if not s: return True left = 0 From 04d060b765a1a9777a48def2c631b035cc7f91b5 Mon Sep 17 00:00:00 2001 From: Shichao An Date: Wed, 23 Sep 2015 11:57:34 -0700 Subject: [PATCH 34/35] Added --- linked_list_cycle/solution.py | 17 +++++-- palindrome_linked_list/solution.py | 19 +++++++ .../solution.py | 49 +++++++++++++++++-- remove_linked_list_elements/solution.py | 39 +++++++++++++++ 4 files changed, 115 insertions(+), 9 deletions(-) create mode 100644 palindrome_linked_list/solution.py create mode 100644 remove_linked_list_elements/solution.py diff --git a/linked_list_cycle/solution.py b/linked_list_cycle/solution.py index a68cb79..448a929 100644 --- a/linked_list_cycle/solution.py +++ b/linked_list_cycle/solution.py @@ -1,13 +1,22 @@ +""" +Given a linked list, determine if it has a cycle in it. + +Follow up: +Can you solve it without using extra space? +""" + # Definition for singly-linked list. -# class ListNode: +# class ListNode(object): # def __init__(self, x): # self.val = x # self.next = None -class Solution: - # @param head, a ListNode - # @return a boolean +class Solution(object): def hasCycle(self, head): + """ + :type head: ListNode + :rtype: bool + """ slow = head fast = head while fast is not None and fast.next is not None: diff --git a/palindrome_linked_list/solution.py b/palindrome_linked_list/solution.py new file mode 100644 index 0000000..7e6da33 --- /dev/null +++ b/palindrome_linked_list/solution.py @@ -0,0 +1,19 @@ +""" +Given a singly linked list, determine if it is a palindrome. + +Follow up: +Could you do it in O(n) time and O(1) space? +""" + +# Definition for singly-linked list. +# class ListNode(object): +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution(object): + def isPalindrome(self, head): + """ + :type head: ListNode + :rtype: bool + """ diff --git a/populating_next_right_pointers_in_each_node/solution.py b/populating_next_right_pointers_in_each_node/solution.py index 5f4c079..8748cc7 100644 --- a/populating_next_right_pointers_in_each_node/solution.py +++ b/populating_next_right_pointers_in_each_node/solution.py @@ -1,15 +1,54 @@ -# Definition for a binary tree node -# class TreeNode: +""" +Given a binary tree + + struct TreeLinkNode { + TreeLinkNode *left; + TreeLinkNode *right; + TreeLinkNode *next; + } + +Populate each next pointer to point to its next right node. If there is no +next right node, the next pointer should be set to NULL. + +Initially, all next pointers are set to NULL. + +Note: + +You may only use constant extra space. +You may assume that it is a perfect binary tree (ie, all leaves are at the +same level, and every parent has two children). + +For example, + +Given the following perfect binary tree, + 1 + / \ + 2 3 + / \ / \ + 4 5 6 7 +After calling your function, the tree should look like: + 1 -> NULL + / \ + 2 -> 3 -> NULL + / \ / \ + 4->5->6->7 -> NULL + +""" + +# Definition for binary tree with next pointer. +# class TreeLinkNode(object): # def __init__(self, x): # self.val = x # self.left = None # self.right = None # self.next = None -class Solution: - # @param root, a tree node - # @return nothing +class Solution(object): def connect(self, root): + """ + :type root: TreeLinkNode + :rtype: nothing + """ if root is not None: if root.left is not None: root.left.next = root.right diff --git a/remove_linked_list_elements/solution.py b/remove_linked_list_elements/solution.py new file mode 100644 index 0000000..6ffd04a --- /dev/null +++ b/remove_linked_list_elements/solution.py @@ -0,0 +1,39 @@ +""" +Remove all elements from a linked list of integers that have value val. + +Example +Given: 1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6, val = 6 +Return: 1 --> 2 --> 3 --> 4 --> 5 +""" + +# Definition for singly-linked list. +# class ListNode(object): +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution(object): + def removeElements(self, head, val): + """ + :type head: ListNode + :type val: int + :rtype: ListNode + """ + if head is None: + return None + current = head + last = None + while current is not None: + if current.val == val: + if last is not None: + # Remove `current` node and `last` node is not changed + last.next = current.next + else: + # `current` is the head node + # Remove the head node and `last` node is still None + head = current.next + last = None + else: + last = current + current = current.next + return head From 6c523ef4759a57433e10271b584eece16f9f05f3 Mon Sep 17 00:00:00 2001 From: Shichao An Date: Thu, 24 Sep 2015 16:57:12 -0700 Subject: [PATCH 35/35] Added --- product_of_array_except_self/solution2.py | 3 +- product_of_array_except_self/solution4.py | 2 ++ search_insert_position/solution2.py | 44 +++++++++++++++++++++++ unique_binary_search_trees/solution.py | 35 ++++++++++++++++++ unique_binary_search_trees/solution2.py | 28 +++++++++++++++ 5 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 search_insert_position/solution2.py create mode 100644 unique_binary_search_trees/solution.py create mode 100644 unique_binary_search_trees/solution2.py diff --git a/product_of_array_except_self/solution2.py b/product_of_array_except_self/solution2.py index 6305c06..8400207 100644 --- a/product_of_array_except_self/solution2.py +++ b/product_of_array_except_self/solution2.py @@ -27,8 +27,7 @@ def productExceptSelf(self, nums): for i in range(1, n): for j in range(i): res[j] *= nums[i] - if i > 0: - product *= nums[i - 1] + product *= nums[i - 1] res[i] = product return res diff --git a/product_of_array_except_self/solution4.py b/product_of_array_except_self/solution4.py index 609beac..37dcf71 100644 --- a/product_of_array_except_self/solution4.py +++ b/product_of_array_except_self/solution4.py @@ -23,6 +23,8 @@ def productExceptSelf(self, nums): res = [1 for i in range(n)] # Scan from left to right for i in range(1, n): + # i is from 1 to n - 1 + # res[i] is the product accumulated to the left res[i] = res[i - 1] * nums[i - 1] # right_product is the product accumulated to the right diff --git a/search_insert_position/solution2.py b/search_insert_position/solution2.py new file mode 100644 index 0000000..d180e73 --- /dev/null +++ b/search_insert_position/solution2.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +""" +Given a sorted array and a target value, return the index if the target is +found. If not, return the index where it would be if it were inserted in +order. + +You may assume no duplicates in the array. + +Here are few examples. +[1,3,5,6], 5 → 2 +[1,3,5,6], 2 → 1 +[1,3,5,6], 7 → 4 +[1,3,5,6], 0 → 0 + +""" + +class Solution(object): + def searchInsert(self, nums, target): + n = len(nums) + left = 0 + right = n - 1 + while left + 1 < right: + mid = left + (right - left) / 2 + if mid > 0 and nums[mid - 1] < target < nums[mid]: + return mid + elif target <= nums[mid]: + right = mid + else: + left = mid + if nums[left] < target < nums[right]: + return left + 1 + elif nums[left] == target: + return left + elif nums[right] == target: + return right + elif nums[left] > target: + return min(0, left) + elif nums[right] < target: + return max(n, right) + + +a1 = [1, 3] +s = Solution() +print s.searchInsert(a1, 2) diff --git a/unique_binary_search_trees/solution.py b/unique_binary_search_trees/solution.py new file mode 100644 index 0000000..cb7aad8 --- /dev/null +++ b/unique_binary_search_trees/solution.py @@ -0,0 +1,35 @@ +""" +Given n, how many structurally unique BST's (binary search trees) that store +values 1...n? + +For example, +Given n = 3, there are a total of 5 unique BST's. + + 1 3 3 2 1 + \ / / / \ \ + 3 2 1 1 3 2 + / / \ \ + 2 1 2 3 +""" + +class Solution(object): + def numTrees(self, n): + """ + :type n: int + :rtype: int + """ + t = [-1 for _ in range(n + 1)] + return self.num_trees_aux(n, t) + + def num_trees_aux(self, n, t): + if n == 0 or n == 1: + return 1 + elif t[n] != -1: + return t[n] + else: + res = 0 + for i in range(n): + res += self.num_trees_aux(i, t) * \ + self.num_trees_aux(n - 1 - i, t) + t[n] = res + return res diff --git a/unique_binary_search_trees/solution2.py b/unique_binary_search_trees/solution2.py new file mode 100644 index 0000000..ee55f5d --- /dev/null +++ b/unique_binary_search_trees/solution2.py @@ -0,0 +1,28 @@ +""" +Given n, how many structurally unique BST's (binary search trees) that store +values 1...n? + +For example, +Given n = 3, there are a total of 5 unique BST's. + + 1 3 3 2 1 + \ / / / \ \ + 3 2 1 1 3 2 + / / \ \ + 2 1 2 3 +""" + +class Solution(object): + def numTrees(self, n): + t = [-1 for _ in range(n + 1)] + t[0] = 1 + t[1] = 1 + if n <= 1: + return t[n] + else: + for i in range(2, n + 1): + res = 0 + for j in range(i): + res += t[j] * t[i - 1 - j] + t[i] = res + return t[n]