diff --git a/100-200q/125.py b/100-200q/125.py index 24c0119..6190812 100644 --- a/100-200q/125.py +++ b/100-200q/125.py @@ -25,4 +25,7 @@ def numDistinct(self, s, t): dp[r][c] = dp[r-1][c] if s[r-1] == t[c-1]: dp[r][c] += dp[r-1][c-1] - return dp[row][col] \ No newline at end of file + return dp[row][col] + +# Time: O(N^2) +# Space: O(N^2) \ No newline at end of file diff --git a/100-200q/127.py b/100-200q/127.py new file mode 100644 index 0000000..efe509b --- /dev/null +++ b/100-200q/127.py @@ -0,0 +1,62 @@ +''' + Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that: + + Only one letter can be changed at a time. + Each transformed word must exist in the word list. Note that beginWord is not a transformed word. + Note: + + Return 0 if there is no such transformation sequence. + All words have the same length. + All words contain only lowercase alphabetic characters. + You may assume no duplicates in the word list. + You may assume beginWord and endWord are non-empty and are not the same. + Example 1: + + Input: + beginWord = "hit", + endWord = "cog", + wordList = ["hot","dot","dog","lot","log","cog"] + + Output: 5 + + Explanation: As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog", + return its length 5. +''' + +class Solution(object): + def ladderLength(self, beginWord, endWord, wordList): + """ + :type beginWord: str + :type endWord: str + :type wordList: List[str] + :rtype: int + """ + d = {} + for word in wordList: + for i in range(len(word)): + s = word[:i] + "_" + word[i+1:] + if s in d: + d[s].append(word) + else: + d[s] = [word] + + queue, visited = [], set() + queue.append((beginWord, 1)) + while queue: + word, steps = queue.pop(0) + if word not in visited: + visited.add(word) + + if word == endWord: + return steps + else: + for index in range(len(word)): + s = word[:index] + "_" + word[index+1:] + neigh_words = [] + if s in d: + neigh_words = d[s] + + for neigh in neigh_words: + if neigh not in visited: + queue.append((neigh, steps+1)) + return 0 diff --git a/100-200q/128.py b/100-200q/128.py new file mode 100644 index 0000000..7eef2ca --- /dev/null +++ b/100-200q/128.py @@ -0,0 +1,31 @@ +''' + Given an unsorted array of integers, find the length of the longest consecutive elements sequence. + + Your algorithm should run in O(n) complexity. + + Example: + + Input: [100, 4, 200, 1, 3, 2] + Output: 4 + Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4. +''' + +class Solution(object): + def longestConsecutive(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + result = 0 + nums = set(nums) + + for num in nums: + if num-1 not in nums: + curr = num + length = 1 + + while curr+1 in nums: + curr += 1 + length += 1 + result = max(result, length) + return result \ No newline at end of file diff --git a/100-200q/129.py b/100-200q/129.py new file mode 100644 index 0000000..64d8c47 --- /dev/null +++ b/100-200q/129.py @@ -0,0 +1,49 @@ +''' +Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number. + +An example is the root-to-leaf path 1->2->3 which represents the number 123. + +Find the total sum of all root-to-leaf numbers. + +Note: A leaf is a node with no children. + +Example: + +Input: [1,2,3] + 1 + / \ + 2 3 +Output: 25 +Explanation: +The root-to-leaf path 1->2 represents the number 12. +The root-to-leaf path 1->3 represents the number 13. +Therefore, sum = 12 + 13 = 25. +''' + +# 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 sumNumbers(self, root): + """ + :type root: TreeNode + :rtype: int + """ + if not root: + return 0 + + def dfs(root, num, total): + if not root: + return total + num = num*10 + root.val + if not root.left and not root.right: + total += num + return total + + return dfs(root.left, num) + dfs(root.right, num) + + return dfs(root, 0, 0) \ No newline at end of file diff --git a/100-200q/130.py b/100-200q/130.py new file mode 100644 index 0000000..9effdda --- /dev/null +++ b/100-200q/130.py @@ -0,0 +1,26 @@ +''' + Given a 2D board containing 'X' and 'O' (the letter O), capture all regions surrounded by 'X'. + + A region is captured by flipping all 'O's into 'X's in that surrounded region. + + Example: + + X X X X + X O O X + X X O X + X O X X + After running your function, the board should be: + + X X X X + X X X X + X X X X + X O X X +''' + +class Solution(object): + def solve(self, board): + """ + :type board: List[List[str]] + :rtype: void Do not return anything, modify board in-place instead. + """ + \ No newline at end of file diff --git a/100-200q/131.py b/100-200q/131.py new file mode 100644 index 0000000..57d1857 --- /dev/null +++ b/100-200q/131.py @@ -0,0 +1,25 @@ +''' + Given a string s, partition s such that every substring of the partition is a palindrome. + + Return all possible palindrome partitioning of s. +''' + +class Solution(object): + def partition(self, s): + result = [] + def valid(s): + for i in range(len(s)/2): + if s[i] != s[-(i+1)]: + return False + return True + + def partitionRec(curr, s, i): + if i == len(s): + result.append(curr) + else: + for j in range(i, len(s)): + if valid(s[i:j+1]): + partitionRec(curr + [s[i:j+1]], s, j+1) + + partitionRec([], s, 0) + return result \ No newline at end of file diff --git a/100-200q/134.py b/100-200q/134.py new file mode 100644 index 0000000..ac327c5 --- /dev/null +++ b/100-200q/134.py @@ -0,0 +1,28 @@ +''' + There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. + + You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations. + + Return the starting gas station's index if you can travel around the circuit once in the clockwise direction, otherwise return -1. +''' + +class Solution(object): + def canCompleteCircuit(self, gas, cost): + """ + :type gas: List[int] + :type cost: List[int] + :rtype: int + """ + start, curr_sum, total_sum =0, 0, 0 + for index in range(len(gas)): + diff = gas[index] - cost[index] + total_sum += diff + curr_sum += diff + + if curr_sum < 0: + start = index + 1 + curr_sum = 0 + + if total_sum >= 0: + return start + return -1 \ No newline at end of file diff --git a/100-200q/139.py b/100-200q/139.py index 0920250..d24e304 100644 --- a/100-200q/139.py +++ b/100-200q/139.py @@ -25,5 +25,5 @@ def wordBreak(self, s, wordDict): for j in range(i, -1, -1): if dp[j] and s[j:i+1] in wordDict: dp[i+1] = True - wordBreak + break return dp[len(s)] \ No newline at end of file diff --git a/100-200q/141.py b/100-200q/141.py new file mode 100644 index 0000000..24f6c23 --- /dev/null +++ b/100-200q/141.py @@ -0,0 +1,30 @@ +''' + 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(object): +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution(object): + def hasCycle(self, head): + """ + :type head: ListNode + :rtype: bool + """ + + if not head: + return False + + slow, fast = head,head + while fast and fast.next: + slow = slow.next + fast = fast.next.next + if slow == fast: + return True + return False \ No newline at end of file diff --git a/100-200q/148.py b/100-200q/148.py new file mode 100644 index 0000000..1350778 --- /dev/null +++ b/100-200q/148.py @@ -0,0 +1,62 @@ +''' + Sort a linked list in O(n log n) time using constant space complexity. + + Example 1: + + Input: 4->2->1->3 + Output: 1->2->3->4 +''' + +# Definition for singly-linked list. +# class ListNode(object): +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution(object): + def sortList(self, head): + """ + :type head: ListNode + :rtype: ListNode + """ + + if not head or not head.next: + return head + + slow, fast = head, head.next + + while fast.next and fast.next.next: + slow = slow.next + fast = fast.next.next + + head1, head2 = head, slow.next + slow.next = None + head1 = self.sortList(head1) + head2 = self.sortList(head2) + head = self.merge(head1, head2) + return head + + def merge(self, head1, head2): + if not head1: + return head2 + if not head2: + return head1 + + result = ListNode(0) + p = result + + while head1 and head2: + if head1.val <= head2.val: + p.next = ListNode(head1.val) + head1 = head1.next + p = p.next + else: + p.next = ListNode(head2.val) + head2 = head2.next + p = p.next + + if head1: + p.next = head1 + if head2: + p.next = head2 + return result.next \ No newline at end of file diff --git a/100-200q/155.py b/100-200q/155.py new file mode 100644 index 0000000..85232e4 --- /dev/null +++ b/100-200q/155.py @@ -0,0 +1,86 @@ +''' + Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. + + push(x) -- Push element x onto stack. + pop() -- Removes the element on top of the stack. + top() -- Get the top element. + getMin() -- Retrieve the minimum element in the stack. + Example: + MinStack minStack = new MinStack(); + minStack.push(-2); + minStack.push(0); + minStack.push(-3); + minStack.getMin(); --> Returns -3. + minStack.pop(); + minStack.top(); --> Returns 0. + minStack.getMin(); --> Returns -2. +''' + +class MinStack(object): + + def __init__(self): + """ + initialize your data structure here. + """ + self.stack = [] + self.minimum = float('inf') + + def push(self, x): + """ + :type x: int + :rtype: void + """ + if not self.stack: + self.stack.append(x) + self.minimum = x + else: + if x < self.minimum: + self.stack.append(2*x-self.minimum) + self.minimum = x + else: + self.stack.append(x) + + print self.stack + + + def pop(self): + """ + :rtype: void + """ + if self.stack: + top = self.stack.pop() + if top < self.minimum: + self.minimum = 2*self.minimum - top + + + def top(self): + """ + :rtype: int + """ + if not self.stack: + return None + else: + top = self.stack[-1] + if top < self.minimum: + return self.minimum + else: + return top + + + def getMin(self): + """ + :rtype: int + """ + if self.stack: + return self.minimum + else: + return None + + + +# Your MinStack object will be instantiated and called as such: +# obj = MinStack() +# obj.push(x) +# obj.pop() +# param_3 = obj.top() +# param_4 = obj.getMin() \ No newline at end of file diff --git a/100-200q/160.py b/100-200q/160.py new file mode 100644 index 0000000..b8a6d74 --- /dev/null +++ b/100-200q/160.py @@ -0,0 +1,35 @@ +''' + Write a program to find the node at which the intersection of two singly linked lists begins. + + + For example, the following two linked lists: + + A: a1 → a2 + ↘ + c1 → c2 → c3 + ↗ + B: b1 → b2 → b3 + begin to intersect at node c1. +''' + +# Definition for singly-linked list. +# class ListNode(object): +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution(object): + def getIntersectionNode(self, headA, headB): + """ + :type head1, head1: ListNode + :rtype: ListNode + """ + if not headA or not headB: + return None + + pa, pb = headA, headB + while pa != pb: + pa = pa.next if pa is not None else headB + pb = pb.next if pb is not None else headA + + return pa if pa else None \ No newline at end of file diff --git a/100-200q/162.py b/100-200q/162.py new file mode 100644 index 0000000..e8abf10 --- /dev/null +++ b/100-200q/162.py @@ -0,0 +1,30 @@ +''' + A peak element is an element that is greater than its neighbors. + + Given an input array nums, where nums[i] ≠ nums[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 nums[-1] = nums[n] = -∞. + + Example 1: + + Input: nums = [1,2,3,1] + Output: 2 + Explanation: 3 is a peak element and your function should return the index number 2. +''' + +class Solution(object): + def findPeakElement(self, nums): + """ + :type nums: List[int] + :rtype: int + """ + left, right = 0, len(nums)-1 + while left < right: + mid = (left + right) /2 + if nums[mid] > nums[mid+1]: + right = mid + else: + left = mid + 1 + return left \ No newline at end of file diff --git a/100-200q/179.py b/100-200q/179.py new file mode 100644 index 0000000..70b9d7f --- /dev/null +++ b/100-200q/179.py @@ -0,0 +1,21 @@ +''' + Given a list of non negative integers, arrange them such that they form the largest number. + + Example 1: + + Input: [10,2] + Output: "210" + Example 2: + + Input: [3,30,34,5,9] + Output: "9534330" +# ''' + + +class Solution: + # @param {integer[]} nums + # @return {string} + def largestNumber(self, nums): + nums = [str(num) for num in nums] + nums.sort(cmp=lambda x, y : cmp(y+x, x+y)) + return ''.join(nums).lstrip("0") or "0" \ No newline at end of file diff --git a/100-200q/191.py b/100-200q/191.py new file mode 100644 index 0000000..1528f37 --- /dev/null +++ b/100-200q/191.py @@ -0,0 +1,15 @@ +class Solution(object): + def hammingWeight(self, n): + """ + :type n: int + :rtype: int + """ + bits = 0 + mask = 1 + + for i in range(32): + if (n&mask) != 0: + bits +=1 + mask <<= 1 + + return bits \ No newline at end of file diff --git a/200-300q/200.py b/200-300q/200.py new file mode 100644 index 0000000..ac3ffed --- /dev/null +++ b/200-300q/200.py @@ -0,0 +1,30 @@ +class Solution(object): + def numIslands(self, grid): + """ + :type grid: List[List[str]] + :rtype: int + """ + if not grid: + return 0 + + count = 0 + for row in range(len(grid)): + for col in range(len(grid[0])): + if grid[row][col] == '1': + count +=1 + self.merge(grid, row, col) + + return count + + def merge(self, grid, row, col): + if 0 > row or row >= len(grid) or col < 0 or col >= len(grid[0]): + return + + if grid[row][col] != '1': + return + + grid[row][col] = '#' + self.merge(grid, row+1, col) + self.merge(grid, row-1, col) + self.merge(grid, row, col+1) + self.merge(grid, row, col-1) diff --git a/200-300q/203.py b/200-300q/203.py new file mode 100644 index 0000000..6e741bf --- /dev/null +++ b/200-300q/203.py @@ -0,0 +1,22 @@ +class Solution(object): + def countPrimes(self, n): + """ + :type n: int + :rtype: int + """ + if n < 2: + return 0 + + A = [0] * (n + 1) + count = 0 + + for pointer1 in range(2, n): + if A[pointer1] == 0: + count += 1 + pointer2 = pointer1 + while (pointer2 + pointer1 < n): + pointer2 += pointer1 + A[pointer2] = 1 + + return count + \ No newline at end of file diff --git a/200-300q/206.py b/200-300q/206.py new file mode 100644 index 0000000..f0cfaf2 --- /dev/null +++ b/200-300q/206.py @@ -0,0 +1,31 @@ +''' + Reverse a singly linked list. + + Example: + + Input: 1->2->3->4->5->NULL + Output: 5->4->3->2->1->NULL +''' + +# 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 + """ + if not head: + return None + + prev, curr = None, head + while curr: + temp = curr.next + curr.next = prev + prev = curr + curr = temp + return prev \ No newline at end of file diff --git a/200-300q/207.py b/200-300q/207.py new file mode 100644 index 0000000..cd38c5d --- /dev/null +++ b/200-300q/207.py @@ -0,0 +1,52 @@ +''' + 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? + + Example 1: + + Input: 2, [[1,0]] + Output: true + Explanation: There are a total of 2 courses to take. + To take course 1 you should have finished course 0. So it is possible. + +''' + +class Solution(object): + def canFinish(self, numCourses, prerequisites): + """ + :type numCourses: int + :type prerequisites: List[List[int]] + :rtype: bool + """ + + graph = [[] for _ in range(numCourses)] + visited = [False for _ in range(numCourses)] + stack = [False for _ in range(numCourses)] + + for pair in prerequisites: + x, y = pair + graph[x].append(y) + + for course in range(numCourses): + if visited[course] == False: + if self.dfs(graph, visited, stack, course): + return False + return True + + def dfs(self, graph, visited, stack, course): + visited[course] = True + stack[course] = True + + for neigh in graph[course]: + if visited[neigh] == False: + if self.dfs(graph, visited, stack, neigh): + return True + + elif stack[neigh]: + return True + stack[course] = False + return False + \ No newline at end of file diff --git a/200-300q/208.py b/200-300q/208.py new file mode 100644 index 0000000..c5eb9e6 --- /dev/null +++ b/200-300q/208.py @@ -0,0 +1,62 @@ +''' + Implement a trie with insert, search, and startsWith methods. +''' +class TreeNode(object): + self.word = False + self.children = {} + +class Trie(object): + + def __init__(self): + """ + Initialize your data structure here. + """ + self.root = TreeNode() + + def insert(self, word): + """ + Inserts a word into the trie. + :type word: str + :rtype: void + """ + node = self.root + for char in word: + if char not in node.children: + node.children[char] = TreeNode() + node = node.children[char] + node.word = True + + def search(self, word): + """ + Returns if the word is in the trie. + :type word: str + :rtype: bool + """ + node = self.root + for char in word: + if char not in node.children: + return False + node = node.children[char] + return node.word + + + def startsWith(self, prefix): + """ + Returns if there is any word in the trie that starts with the given prefix. + :type prefix: str + :rtype: bool + """ + node = self.root + for char in prefix: + if char not in node.children: + return False + node = node.children[char] + return True + + + +# Your Trie object will be instantiated and called as such: +# obj = Trie() +# obj.insert(word) +# param_2 = obj.search(word) +# param_3 = obj.startsWith(prefix) \ No newline at end of file diff --git a/200-300q/210.py b/200-300q/210.py new file mode 100644 index 0000000..6727580 --- /dev/null +++ b/200-300q/210.py @@ -0,0 +1,53 @@ +''' + 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, return the ordering of courses you should take to finish all courses. + + There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array. + + Example 1: + + Input: 2, [[1,0]] + Output: [0,1] + Explanation: There are a total of 2 courses to take. To take course 1 you should have finished + course 0. So the correct course order is [0,1] . +''' + +class Solution(object): + def findOrder(self, numCourses, prerequisites): + """ + :type numCourses: int + :type prerequisites: List[List[int]] + :rtype: List[int] + """ + graph = [[] for _ in range(numCourses)] + visited = [False for _ in range(numCourses)] + stack = [False for _ in range(numCourses)] + + for pair in prerequisites: + x, y = pair + graph[x].append(y) + + result = [] + for course in range(numCourses): + if visited[course] == False: + if self.dfs(graph, visited, stack, course, result): + return [] + return result + + def dfs(self, graph, visited, stack, course, result): + visited[course] = True + stack[course] = True + + for neigh in graph[course]: + if visited[neigh] == False: + if self.dfs(graph, visited, stack, neigh, result): + return True + + elif stack[neigh]: + return True + stack[course] = False + result.append(course) + return False \ No newline at end of file