├── pic ├── 22.png └── 309.png ├── README.md ├── Leetcode ├── 292.py ├── 9.py ├── 371.py ├── 169.py ├── 217.py ├── 349.py ├── 190.py ├── 191.py ├── 260.py ├── 69.py ├── 231.py ├── 461.py ├── 67.py ├── 125.py ├── 136.py ├── 66.py ├── 392.py ├── 242.py ├── 172.py ├── 342.py ├── 88.py ├── 171.py ├── 401.py ├── 202.py ├── 58.py ├── 27.py ├── 28.py ├── 387.py ├── 367.py ├── 7.py ├── 189.py ├── 344.py ├── 383.py ├── 35.py ├── 1.py ├── 268.py ├── 237.py ├── 374.py ├── 168.py ├── 389.py ├── 26.py ├── 405.py ├── 234.py ├── 303.py ├── 53.py ├── 263.py ├── 299.py ├── 104.py ├── 283.py ├── 219.py ├── 258.py ├── 13.py ├── 198.py ├── 227.py ├── 122.py ├── 205.py ├── 141.py ├── 350.py ├── 322.py ├── 204.py ├── 70.py ├── 1103.py ├── 21.py ├── 160.py ├── 112.py ├── 108.py ├── 14.py ├── 203.py ├── 83.py ├── 167.py ├── 100.py ├── 345.py ├── 101.py ├── 404.py ├── 235.py ├── 8.py ├── 278.py ├── 437.py ├── 994.py ├── 290.py ├── 38.py ├── 111.py ├── 448.py ├── 257.py ├── 面试题57 - II.py ├── 118.py ├── 119.py ├── 206.py ├── 121.py ├── 2.py ├── 面试题59 - II.py ├── 538.py ├── 20.py ├── 3.py ├── 225.py ├── 107.py ├── 155.py ├── 232.py ├── 110.py └── 102.py ├── 344.md ├── 371.md ├── 9.md ├── 67.md ├── 125.md ├── 14.md ├── 172.md ├── 217.md ├── 169.md ├── 234.md ├── 137.md ├── 153.md ├── 58.md ├── 46.md ├── 27.md ├── 53.md ├── 119.md ├── 168.md ├── 219.md ├── 189.md ├── 26.md ├── 378.md ├── 104.md ├── 263.md ├── 121.md ├── 389.md ├── 268.md ├── 122.md ├── 345.md ├── 108.md ├── 111.md ├── 118.md ├── 203.md ├── 326.md ├── 383.md ├── 171.md ├── 343.md ├── 199.md ├── 241.md ├── 110.md ├── 66.md ├── 202.md ├── 342.md ├── 22.md ├── 141.md ├── 377.md ├── 223.md ├── 7.md ├── 88.md ├── 1.md ├── 38.md ├── 89.md ├── 347.md ├── 112.md ├── 102.md ├── 19.md ├── 20.md ├── 216.md ├── 36.md ├── 107.md ├── 278.md ├── 349.md ├── 100.md ├── 230.md ├── 96.md ├── 392.md ├── 70.md ├── 12.md ├── 167.md ├── 374.md ├── 35.md ├── 309.md ├── 62.md ├── 303.md ├── 231.md ├── 319.md ├── 290.md ├── 242.md ├── 198.md ├── 59.md ├── 384.md ├── 173.md ├── 226.md ├── 423.md ├── 232.md ├── 83.md ├── 394.md ├── 205.md ├── 292.md ├── 357.md ├── 54.md ├── 225.md ├── 13.md ├── 190.md ├── 237.md ├── 235.md ├── 6.md ├── 382.md ├── 318.md ├── 94.md ├── 299.md ├── 144.md ├── 350.md ├── 238.md ├── 155.md ├── 260.md └── 136.md /pic/22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xinqiu/My-LeetCode-Notes/HEAD/pic/22.png -------------------------------------------------------------------------------- /pic/309.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xinqiu/My-LeetCode-Notes/HEAD/pic/309.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # My-LeetCode-Notes 2 | I write some notes about the time I try to ac the leetcode problems. 3 | -------------------------------------------------------------------------------- /Leetcode/292.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def canWinNim(self, n): 3 | """ 4 | :type n: int 5 | :rtype: bool 6 | """ 7 | return n % 4 != 0 -------------------------------------------------------------------------------- /Leetcode/9.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def isPalindrome(self, x): 3 | """ 4 | :type x: int 5 | :rtype: bool 6 | """ 7 | 8 | return str(x) == str(x)[::-1] -------------------------------------------------------------------------------- /Leetcode/371.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def getSum(self, a, b): 3 | """ 4 | :type a: int 5 | :type b: int 6 | :rtype: int 7 | """ 8 | return sum([a, b]) -------------------------------------------------------------------------------- /Leetcode/169.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def majorityElement(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: int 6 | """ 7 | return sorted(nums)[len(nums)/2] -------------------------------------------------------------------------------- /Leetcode/217.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def containsDuplicate(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: bool 6 | """ 7 | return len(set(nums)) != len(nums) -------------------------------------------------------------------------------- /Leetcode/349.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def intersection(self, nums1, nums2): 3 | """ 4 | :type nums1: List[int] 5 | :type nums2: List[int] 6 | :rtype: List[int] 7 | """ 8 | 9 | return set(nums1) & set(nums2) -------------------------------------------------------------------------------- /Leetcode/190.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param n, an integer 3 | # @return an integer 4 | def reverseBits(self, n): 5 | return int(bin(n)[2:].zfill(32)[::-1], 2) 6 | 7 | solution = Solution() 8 | 9 | print solution.reverseBits(00000010100101000001111010011100) -------------------------------------------------------------------------------- /Leetcode/191.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def hammingWeight(self, n): 3 | """ 4 | :type n: int 5 | :rtype: int 6 | """ 7 | return bin(n).count('1') 8 | 9 | 10 | 11 | solution = Solution() 12 | 13 | print solution.hammingWeight(3) -------------------------------------------------------------------------------- /Leetcode/260.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def singleNumber(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: List[int] 6 | """ 7 | t = reduce(lambda x, y: x^y, nums) 8 | return list(set(map(lambda x: t ^ x, nums)) & set(nums)) -------------------------------------------------------------------------------- /Leetcode/69.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def mySqrt(self, x): 3 | """ 4 | :type x: int 5 | :rtype: int 6 | """ 7 | import math 8 | return int(math.sqrt(x)) 9 | 10 | solution = Solution() 11 | 12 | print solution.mySqrt(4) -------------------------------------------------------------------------------- /Leetcode/231.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def isPowerOfTwo(self, n): 3 | """ 4 | :type n: int 5 | :rtype: bool 6 | """ 7 | return n > 0 and (n & (n-1)) == 0 8 | 9 | 10 | solution = Solution() 11 | 12 | print solution.isPowerOfTwo(4) -------------------------------------------------------------------------------- /Leetcode/461.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def hammingDistance(self, x, y): 3 | """ 4 | :type x: int 5 | :type y: int 6 | :rtype: int 7 | """ 8 | return bin(x ^ y).count('1') 9 | 10 | 11 | solution = Solution() 12 | 13 | print solution.hammingDistance(1, 4) -------------------------------------------------------------------------------- /Leetcode/67.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def addBinary(self, a, b): 3 | """ 4 | :type a: str 5 | :type b: str 6 | :rtype: str 7 | """ 8 | return bin(int(a, 2)+int(b, 2))[2:] 9 | 10 | solution = Solution() 11 | 12 | print solution.addBinary("1010", "1011") -------------------------------------------------------------------------------- /Leetcode/125.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def isPalindrome(self, s): 3 | """ 4 | :type s: str 5 | :rtype: bool 6 | """ 7 | t = [c for c in s.lower() if c.isalpha()] 8 | return t == t[::-1] 9 | 10 | solution = Solution() 11 | 12 | print solution.isPalindrome("OP") -------------------------------------------------------------------------------- /Leetcode/136.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def singleNumber(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: int 6 | """ 7 | return reduce(lambda x, y: x^y, nums) 8 | 9 | 10 | solution = Solution() 11 | 12 | print solution.singleNumber([2, 2, 1, 3, 1]) 13 | -------------------------------------------------------------------------------- /Leetcode/66.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def plusOne(self, digits): 3 | """ 4 | :type digits: List[int] 5 | :rtype: List[int] 6 | """ 7 | return [int(c) for c in str(int(''.join(map(str, digits)))+1)] 8 | 9 | 10 | solution = Solution() 11 | 12 | print solution.plusOne([9]) -------------------------------------------------------------------------------- /Leetcode/392.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def isSubsequence(self, s, t): 3 | """ 4 | :type s: str 5 | :type t: str 6 | :rtype: bool 7 | """ 8 | t = iter(t) 9 | return all(c in t for c in s) 10 | 11 | 12 | solution = Solution() 13 | 14 | print solution.isSubsequence('acb', 'ahbgdc') -------------------------------------------------------------------------------- /Leetcode/242.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def isAnagram(self, s, t): 3 | """ 4 | :type s: str 5 | :type t: str 6 | :rtype: bool 7 | """ 8 | from collections import Counter 9 | return Counter(s) == Counter(t) 10 | 11 | solution = Solution() 12 | 13 | print solution.isAnagram('aacc', 'ccac') -------------------------------------------------------------------------------- /Leetcode/172.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def trailingZeroes(self, n): 3 | """ 4 | :type n: int 5 | :rtype: int 6 | """ 7 | ret = 0 8 | while n >= 5: 9 | ret += n / 5 10 | n /= 5 11 | return ret 12 | 13 | solution = Solution() 14 | 15 | print solution.trailingZeroes(25) -------------------------------------------------------------------------------- /Leetcode/342.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def isPowerOfFour(self, num): 3 | """ 4 | :type num: int 5 | :rtype: bool 6 | """ 7 | 8 | return bin(num)[2] == "1" and len(bin(num)[3:]) % 2 == 0 \ 9 | and bin(num)[2:].count("1") == 1 10 | 11 | solution = Solution() 12 | 13 | solution.isPowerOfFour(2) -------------------------------------------------------------------------------- /Leetcode/88.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def merge(self, nums1, m, nums2, n): 3 | """ 4 | :type nums1: List[int] 5 | :type m: int 6 | :type nums2: List[int] 7 | :type n: int 8 | :rtype: None Do not return anything, modify nums1 in-place instead. 9 | """ 10 | nums1[m:m+n] = nums2 11 | nums1.sort() -------------------------------------------------------------------------------- /Leetcode/171.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def titleToNumber(self, s): 3 | """ 4 | :type s: str 5 | :rtype: int 6 | """ 7 | ret = 0 8 | for c in s: 9 | ret = (ord(c) - ord('A') + 1) + ret * 26 10 | return ret 11 | 12 | 13 | s = 'ZY' 14 | 15 | print reduce(lambda x, y: x*26+y,[ord(c)-ord('A')+1 for c in s]) -------------------------------------------------------------------------------- /Leetcode/401.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def readBinaryWatch(self, num): 3 | """ 4 | :type num: int 5 | :rtype: List[str] 6 | """ 7 | return ["%d:%02d" % (h, m) for h in range(12) for m in range(60) if bin(h).count('1')+bin(m).count('1') == num] 8 | 9 | solution = Solution() 10 | 11 | print solution.readBinaryWatch(1) 12 | 13 | print -------------------------------------------------------------------------------- /Leetcode/202.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def isHappy(self, n): 3 | """ 4 | :type n: int 5 | :rtype: bool 6 | """ 7 | 8 | while n != 1: 9 | n = sum([int(c) ** 2 for c in str(n)]) 10 | if n == 4: 11 | return False 12 | return True 13 | 14 | solution = Solution() 15 | 16 | print solution.isHappy(19) -------------------------------------------------------------------------------- /Leetcode/58.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def lengthOfLastWord(self, s): 3 | """ 4 | :type s: str 5 | :rtype: int 6 | """ 7 | if ' ' not in s: 8 | return len(s) 9 | else: 10 | return len(s.split()[-1]) if len(s.split()) > 0 else 0 11 | 12 | solution = Solution() 13 | 14 | 15 | print solution.lengthOfLastWord('1 ') -------------------------------------------------------------------------------- /Leetcode/27.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def removeElement(self, nums, val): 3 | """ 4 | :type nums: List[int] 5 | :type val: int 6 | :rtype: int 7 | """ 8 | 9 | while val in nums: 10 | nums.remove(val) 11 | 12 | return nums 13 | 14 | solution = Solution() 15 | 16 | print(solution.removeElement([0,1,2,2,3,0,4,2], 2)) -------------------------------------------------------------------------------- /Leetcode/28.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def strStr(self, haystack, needle): 3 | """ 4 | :type haystack: str 5 | :type needle: str 6 | :rtype: int 7 | """ 8 | if needle not in haystack: 9 | return -1 10 | else: 11 | return haystack.index(needle) 12 | 13 | solution = Solution() 14 | 15 | print solution.strStr("aaaaa", "bba") -------------------------------------------------------------------------------- /Leetcode/387.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def firstUniqChar(self, s): 3 | """ 4 | :type s: str 5 | :rtype: int 6 | """ 7 | 8 | for c in s: 9 | if s.index(c) == len(s) - 1 - s[::-1].index(c): 10 | return s.index(c) 11 | return -1 12 | 13 | 14 | solution = Solution() 15 | 16 | print solution.firstUniqChar("loveleetcode") 17 | -------------------------------------------------------------------------------- /Leetcode/367.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def isPerfectSquare(self, num): 3 | """ 4 | :type num: int 5 | :rtype: bool 6 | """ 7 | # return num ** 0.5 == int(num ** 0.5) 8 | 9 | if num < 2: 10 | return True 11 | 12 | x = num // 2 13 | while x * x > num: 14 | x = (x + num // x) // 2 15 | return x * x == num 16 | -------------------------------------------------------------------------------- /Leetcode/7.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def reverse(self, x): 3 | """ 4 | :type x: int 5 | :rtype: int 6 | """ 7 | ret = int(str(x)[::-1]) if x >= 0 else -int(str(x)[1:][::-1]) 8 | 9 | if -2**31 <= ret <= 2**31-1: 10 | return ret 11 | else: 12 | return 0 13 | 14 | 15 | solution = Solution() 16 | 17 | print(solution.reverse(123)) -------------------------------------------------------------------------------- /Leetcode/189.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def rotate(self, nums, k): 3 | """ 4 | :type nums: List[int] 5 | :type k: int 6 | :rtype: None Do not return anything, modify nums in-place instead. 7 | """ 8 | nums[:] = nums[-k % len(nums):] + nums[:-k % len(nums)] 9 | return nums 10 | 11 | solution = Solution() 12 | 13 | print solution.rotate([1,2,3,4,5,6,7], 3) -------------------------------------------------------------------------------- /Leetcode/344.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def reverseString(self, s): 3 | """ 4 | :type s: List[str] 5 | :rtype: None Do not return anything, modify s in-place instead. 6 | """ 7 | i, j = 0, len(s) - 1 8 | while i < j: 9 | s[i], s[j] = s[j], s[i] 10 | i += 1 11 | j -= 1 12 | return s 13 | 14 | # return s.reverse() -------------------------------------------------------------------------------- /Leetcode/383.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def canConstruct(self, ransomNote, magazine): 3 | """ 4 | :type ransomNote: str 5 | :type magazine: str 6 | :rtype: bool 7 | """ 8 | from collections import Counter 9 | 10 | return len(Counter(ransomNote) - Counter(magazine)) == 0 11 | 12 | 13 | solution = Solution() 14 | 15 | print solution.canConstruct("aa", "ab") -------------------------------------------------------------------------------- /Leetcode/35.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def searchInsert(self, nums, target): 3 | """ 4 | :type nums: List[int] 5 | :type target: int 6 | :rtype: int 7 | """ 8 | if target not in nums: 9 | nums.append(target) 10 | nums = sorted(nums) 11 | 12 | return nums.index(target) 13 | 14 | 15 | solution = Solution() 16 | 17 | print solution.searchInsert([1,3,5,6], 0) -------------------------------------------------------------------------------- /Leetcode/1.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def twoSum(self, nums, target): 3 | """ 4 | :type nums: List[int] 5 | :type target: int 6 | :rtype: List[int] 7 | """ 8 | d = {} 9 | for i, n in enumerate(nums): 10 | if target-n in d: 11 | return d[target-n], i 12 | d[n] = i 13 | 14 | 15 | solution = Solution() 16 | 17 | print(solution.twoSum([2,7,11,15], 9)) -------------------------------------------------------------------------------- /Leetcode/268.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def missingNumber(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: int 6 | """ 7 | # return 1 if nums == [0] else len(nums) * (len(nums)+1) / 2 - sum(nums) 8 | return reduce(lambda x, y: x ^ y, map(lambda x: x[0] ^ x[1], list(enumerate(nums)))) ^ len(nums) 9 | 10 | solution = Solution() 11 | 12 | print solution.missingNumber([9,6,4,2,3,5,7,0,1]) -------------------------------------------------------------------------------- /Leetcode/237.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | # class ListNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.next = None 6 | 7 | class Solution(object): 8 | def deleteNode(self, node): 9 | """ 10 | :type node: ListNode 11 | :rtype: void Do not return anything, modify node in-place instead. 12 | """ 13 | node.val, node.next = node.next.val, node.next.next 14 | 15 | -------------------------------------------------------------------------------- /Leetcode/374.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def guessNumber(self, n): 3 | """ 4 | :type n: int 5 | :rtype: int 6 | """ 7 | low, high = 1, n 8 | 9 | while low <= high: 10 | mid = low + (high-low) // 2 11 | if guess(mid) == 0: 12 | return mid 13 | elif guess(mid) == -1: 14 | high = mid - 1 15 | else: 16 | low = mid + 1 -------------------------------------------------------------------------------- /Leetcode/168.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def convertToTitle(self, n): 3 | """ 4 | :type n: int 5 | :rtype: str 6 | """ 7 | if n <= 0: 8 | return "" 9 | ret = "" 10 | while n > 0: 11 | n -= 1 12 | t = n % 26 13 | ret += str(chr(t+ord('A'))) 14 | n /= 26 15 | return ret[::-1] 16 | 17 | solution = Solution() 18 | 19 | print solution.convertToTitle(701) -------------------------------------------------------------------------------- /Leetcode/389.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def findTheDifference(self, s, t): 3 | """ 4 | :type s: str 5 | :type t: str 6 | :rtype: str 7 | """ 8 | # from collections import Counter 9 | # 10 | # return (Counter(t) - Counter(s)).keys()[0] 11 | 12 | return chr(reduce(lambda x, y: x ^ y, map(ord,s+t))) 13 | 14 | 15 | solution = Solution() 16 | 17 | print solution.findTheDifference("abcd", "abcde") 18 | -------------------------------------------------------------------------------- /Leetcode/26.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def removeDuplicates(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: int 6 | """ 7 | t = None 8 | num = nums[:] 9 | for n in num: 10 | if n != t: 11 | t = n 12 | else: 13 | nums.remove(n) 14 | return len(nums) 15 | 16 | solution = Solution() 17 | 18 | print(solution.removeDuplicates([0,0,1,1,1,2,2,3,3,4])) -------------------------------------------------------------------------------- /Leetcode/405.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def toHex(self, num): 3 | """ 4 | :type num: int 5 | :rtype: str 6 | """ 7 | num = num & 0xFFFFFFFF 8 | 9 | ret = "" 10 | 11 | s = "0123456789abcdef" 12 | 13 | while num > 0: 14 | ret += s[num & 0xf] 15 | num >>= 4 16 | 17 | return ret[::-1] if ret else "0" 18 | 19 | 20 | 21 | solution = Solution() 22 | 23 | print solution.toHex(26) -------------------------------------------------------------------------------- /Leetcode/234.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | # class ListNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.next = None 6 | 7 | class Solution(object): 8 | def isPalindrome(self, head): 9 | """ 10 | :type head: ListNode 11 | :rtype: bool 12 | """ 13 | s = [] 14 | while head: 15 | s.append(head.val) 16 | head = head.next 17 | 18 | return s == s[::-1] -------------------------------------------------------------------------------- /Leetcode/303.py: -------------------------------------------------------------------------------- 1 | class NumArray(object): 2 | 3 | def __init__(self, nums): 4 | """ 5 | :type nums: List[int] 6 | """ 7 | self.nums = nums 8 | self.sums = [0] 9 | for i in range(len(nums)): 10 | self.sums.append(self.sums[i] + nums[i]) 11 | 12 | def sumRange(self, i, j): 13 | """ 14 | :type i: int 15 | :type j: int 16 | :rtype: int 17 | """ 18 | return self.sums[j+1] - self.sums[i] -------------------------------------------------------------------------------- /344.md: -------------------------------------------------------------------------------- 1 | # 344. Reverse String 2 | 3 | ## Intro 4 | 5 | Write a function that takes a string as input and returns the string reversed. 6 | 7 | #### Example 8 | 9 | Given s = "hello", return "olleh". 10 | 11 | ## Think 12 | 13 | Python的内置函数。 14 | 15 | ## Solution 16 | 17 | Python 18 | 19 | ```python 20 | class Solution(object): 21 | def reverseString(self, s): 22 | """ 23 | :type s: str 24 | :rtype: str 25 | """ 26 | return s[::-1] 27 | ``` -------------------------------------------------------------------------------- /Leetcode/53.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def maxSubArray(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: int 6 | """ 7 | ret = nums[0] 8 | t = 0 9 | for n in nums: 10 | if t > 0: 11 | t += n 12 | else: 13 | t = n 14 | ret = max(t, ret) 15 | return ret 16 | 17 | 18 | solution = Solution() 19 | 20 | print solution.maxSubArray([-2,1,-3,4,-1,2,1,-5,4]) -------------------------------------------------------------------------------- /Leetcode/263.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def isUgly(self, num): 3 | """ 4 | :type num: int 5 | :rtype: bool 6 | """ 7 | if num < 1: 8 | return False 9 | 10 | while num % 5 == 0: 11 | num /= 5 12 | 13 | while num % 3 == 0: 14 | num /= 3 15 | 16 | while num % 2 == 0: 17 | num >>= 1 18 | return num == 1 19 | 20 | 21 | 22 | solution = Solution() 23 | 24 | print solution.isUgly(10) -------------------------------------------------------------------------------- /Leetcode/299.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def getHint(self, secret, guess): 3 | """ 4 | :type secret: str 5 | :type guess: str 6 | :rtype: str 7 | """ 8 | A = sum([secret[i] == guess[i] for i in range(len(secret))]) 9 | from collections import Counter 10 | B = sum((Counter(secret) & Counter(guess)).values()) - A 11 | 12 | return "%dA%dB" %(A, B) 13 | 14 | solution = Solution() 15 | 16 | print solution.getHint("11223", "01112") 17 | -------------------------------------------------------------------------------- /Leetcode/104.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class Solution(object): 9 | def maxDepth(self, root): 10 | """ 11 | :type root: TreeNode 12 | :rtype: int 13 | """ 14 | if not root: 15 | return 0 16 | else: 17 | return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right)) -------------------------------------------------------------------------------- /Leetcode/283.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def moveZeroes(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: None Do not return anything, modify nums in-place instead. 6 | """ 7 | count = 0 8 | for i in range(len(nums)): 9 | if nums[i] == 0: 10 | count += 1 11 | elif count > 0: 12 | nums[i-count] = nums[i] 13 | nums[i] = 0 14 | 15 | solution = Solution() 16 | 17 | print solution.moveZeroes([0,1,0,3,12]) 18 | -------------------------------------------------------------------------------- /Leetcode/219.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def containsNearbyDuplicate(self, nums, k): 3 | """ 4 | :type nums: List[int] 5 | :type k: int 6 | :rtype: bool 7 | """ 8 | s = set() 9 | for i in range(len(nums)): 10 | if nums[i] in s: 11 | return True 12 | s.add(nums[i]) 13 | if len(s) > k: 14 | s.remove(nums[i-k]) 15 | return False 16 | 17 | solution = Solution() 18 | 19 | print solution.containsNearbyDuplicate([99, 99], 2) -------------------------------------------------------------------------------- /Leetcode/258.py: -------------------------------------------------------------------------------- 1 | # class Solution(object): 2 | # def addDigits(self, num): 3 | # """ 4 | # :type num: int 5 | # :rtype: int 6 | # """ 7 | # while len(str(num)) != 1: 8 | # num = sum(map(int, str(num))) 9 | # return num 10 | 11 | class Solution(object): 12 | def addDigits(self, num): 13 | """ 14 | :type num: int 15 | :rtype: int 16 | """ 17 | return num if num < 10 else (num-1)%9+1 18 | 19 | solution = Solution() 20 | 21 | print solution.addDigits(0) -------------------------------------------------------------------------------- /371.md: -------------------------------------------------------------------------------- 1 | # 371. Sum of Two Integers 2 | 3 | ## Intro 4 | 5 | Calculate the sum of two integers a and b, but you are not allowed to use the operator `+` and `-`. 6 | 7 | #### Example 8 | 9 | Given a = 1 and b = 2, return 3. 10 | 11 | ## Thinking 12 | 13 | 这个估计是想考大数相加,对于python就容易多了。 14 | 15 | ## Solution 16 | 17 | 18 | Python 19 | 20 | ```python 21 | class Solution(object): 22 | def getSum(self, a, b): 23 | """ 24 | :type a: int 25 | :type b: int 26 | :rtype: int 27 | """ 28 | return a + b 29 | ``` -------------------------------------------------------------------------------- /Leetcode/13.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def romanToInt(self, s): 3 | """ 4 | :type s: str 5 | :rtype: int 6 | """ 7 | d = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000} 8 | 9 | ret = 0 10 | 11 | for i in range(len(s)): 12 | if i < len(s) - 1 and d[s[i]] < d[s[i+1]]: 13 | ret -= d[s[i]] 14 | else: 15 | ret += d[s[i]] 16 | 17 | return ret 18 | 19 | solution = Solution() 20 | 21 | print(solution.romanToInt('MCMXCIV')) -------------------------------------------------------------------------------- /Leetcode/198.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def rob(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: int 6 | """ 7 | if not nums: 8 | return 0 9 | 10 | if len(nums) < 3: 11 | return max(nums) 12 | 13 | dp = [0 for _ in range(len(nums))] 14 | dp[0] = nums[0] 15 | 16 | for i in range(1, len(nums)): 17 | dp[i] = max(dp[i-2]+nums[i], dp[i-1]) 18 | return dp[-1] 19 | 20 | solution = Solution() 21 | 22 | print solution.rob([1,2,3,1]) -------------------------------------------------------------------------------- /9.md: -------------------------------------------------------------------------------- 1 | # 9. Palindrome Number 2 | 3 | ## Intro 4 | 5 | Determine whether an integer is a palindrome. Do this without extra space. 6 | 7 | ## Thinking 8 | 9 | 转化为字符串然后首尾开始比较。 10 | 11 | ## Solution 12 | 13 | Python 14 | 15 | ```python 16 | class Solution(object): 17 | def isPalindrome(self, x): 18 | """ 19 | :type x: int 20 | :rtype: bool 21 | """ 22 | x = str(x) 23 | for i in range(len(x)): 24 | if x[i] != x[len(x) - i -1]: 25 | return False 26 | return True 27 | ``` -------------------------------------------------------------------------------- /Leetcode/227.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class Solution(object): 9 | def invertTree(self, root): 10 | """ 11 | :type root: TreeNode 12 | :rtype: TreeNode 13 | """ 14 | if root: 15 | root.left, root.right = root.right, root.left 16 | self.invertTree(root.left) 17 | self.invertTree(root.right) 18 | return root -------------------------------------------------------------------------------- /Leetcode/122.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def maxProfit(self, prices): 3 | """ 4 | :type prices: List[int] 5 | :rtype: int 6 | """ 7 | 8 | # ret = 0 9 | # 10 | # for i in range(1, len(prices)): 11 | # if prices[i] > prices[i-1]: 12 | # ret += prices[i] - prices[i-1] 13 | # return ret 14 | 15 | return sum(filter(lambda x:x > 0, [prices[i] - prices[i-1] for i in range(1, len(prices))])) 16 | 17 | solution = Solution() 18 | 19 | print solution.maxProfit([7,1,5,3,6,4]) -------------------------------------------------------------------------------- /Leetcode/205.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def isIsomorphic(self, s, t): 3 | """ 4 | :type s: str 5 | :type t: str 6 | :rtype: bool 7 | """ 8 | d = {} 9 | 10 | if len(set(s)) != len(set(t)): 11 | return False 12 | 13 | for i in range(len(s)): 14 | if s[i] not in d: 15 | d[s[i]] = t[i] 16 | elif d[s[i]] != t[i]: 17 | return False 18 | return True 19 | 20 | solution = Solution() 21 | 22 | print solution.isIsomorphic('ab', 'aa') -------------------------------------------------------------------------------- /Leetcode/141.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | # class ListNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.next = None 6 | 7 | class Solution(object): 8 | def hasCycle(self, head): 9 | """ 10 | :type head: ListNode 11 | :rtype: bool 12 | """ 13 | slow = fast = head 14 | 15 | while fast and fast.next: 16 | slow = slow.next 17 | fast = fast.next.next 18 | 19 | if slow == fast: 20 | return True 21 | return False -------------------------------------------------------------------------------- /Leetcode/350.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def intersect(self, nums1, nums2): 3 | """ 4 | :type nums1: List[int] 5 | :type nums2: List[int] 6 | :rtype: List[int] 7 | """ 8 | ret = [] 9 | 10 | for c in set(nums1) & set(nums2): 11 | ret.extend([c] * min(nums1.count(c), nums2.count(c))) 12 | return ret 13 | 14 | # return [c for c in set(nums1) & set(nums2) for _ in range(min(nums1.count(c), nums2.count(c)))] 15 | 16 | 17 | solution = Solution() 18 | 19 | print solution.intersect([1,2,2,1], [2,2]) -------------------------------------------------------------------------------- /Leetcode/322.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | 3 | def coinChange(self, coins, amount): 4 | """ 5 | :type coins: List[int] 6 | :type amount: int 7 | :rtype: int 8 | """ 9 | 10 | dp = [1e9] * (amount + 1) 11 | dp[0] = 0 12 | 13 | for coin in coins: 14 | for i in range(coin, amount+1): 15 | dp[i] = min(dp[i], dp[i-coin] + 1) 16 | return dp[amount] if dp[amount] != 1e9 else -1 17 | 18 | 19 | solution = Solution() 20 | 21 | print solution.coinChange([186,419,83,408], 6249) 22 | -------------------------------------------------------------------------------- /Leetcode/204.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def countPrimes(self, n): 3 | """ 4 | :type n: int 5 | :rtype: int 6 | """ 7 | 8 | isPrime = [True for _ in range(n)] 9 | 10 | for i in range(2, int(n ** 0.5)+1): 11 | if isPrime[i]: 12 | # for j in range(i ** 2, n, i): 13 | # isPrime[j] = False 14 | isPrime[i*i:n:i] = [False] * ((n - 1 - i * i) // i + 1) 15 | 16 | return sum(isPrime[2:]) 17 | 18 | solution = Solution() 19 | 20 | 21 | print solution.countPrimes(10) -------------------------------------------------------------------------------- /Leetcode/70.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def climbStairs(self, n): 3 | """ 4 | :type n: int 5 | :rtype: int 6 | """ 7 | dp = [0 for _ in range(n+1)] 8 | 9 | if n == 1: 10 | return 1 11 | elif n == 2: 12 | return 2 13 | else: 14 | dp[0] = 1 15 | dp[1] = 1 16 | dp[2] = 2 17 | for i in range(2, n+1): 18 | dp[i] = dp[i-1] + dp[i-2] 19 | return dp[n] 20 | 21 | solution = Solution() 22 | 23 | print solution.climbStairs(4) -------------------------------------------------------------------------------- /Leetcode/1103.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def distributeCandies(self, candies, num_people): 3 | """ 4 | :type candies: int 5 | :type num_people: int 6 | :rtype: List[int] 7 | """ 8 | 9 | ret = [0 for _ in range(num_people)] 10 | 11 | cnt = 0 12 | 13 | while candies != 0: 14 | 15 | ret[cnt % num_people] += min(cnt + 1, candies) 16 | candies -= min(cnt+1, candies) 17 | cnt += 1 18 | 19 | return ret 20 | 21 | solution = Solution() 22 | 23 | print solution.distributeCandies(10, 3) 24 | -------------------------------------------------------------------------------- /Leetcode/21.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | class ListNode: 3 | def __init__(self, x): 4 | self.val = x 5 | self.next = None 6 | 7 | class Solution: 8 | def mergeTwoLists(self, l1, l2): 9 | ret = ListNode(None) 10 | p = ret 11 | while l1 and l2: 12 | if l1.val < l2.val: 13 | p.next, l1 = l1, l1.next 14 | else: 15 | p.next, l2 = l2, l2.next 16 | p = p.next 17 | if l1: 18 | p.next = l1 19 | else: 20 | p.next = l2 21 | return ret -------------------------------------------------------------------------------- /Leetcode/160.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | # class ListNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.next = None 6 | 7 | class Solution(object): 8 | def getIntersectionNode(self, headA, headB): 9 | """ 10 | :type head1, head1: ListNode 11 | :rtype: ListNode 12 | """ 13 | if not headA or not headB: 14 | return None 15 | 16 | p = headA 17 | q = headB 18 | 19 | while p != q: 20 | p = p.next if p else headB 21 | q = q.next if q else headA 22 | 23 | return p -------------------------------------------------------------------------------- /67.md: -------------------------------------------------------------------------------- 1 | # 67. Add Binary 2 | 3 | ## Intro 4 | 5 | Given two binary strings, return their sum (also a binary string). 6 | 7 | For example, 8 | 9 | a = `"11"` 10 | 11 | b = `"1"` 12 | 13 | Return `"100"`. 14 | 15 | ## Think 16 | 17 | Python的内置函数很强大, 用int()就可以将字符串转换为整型,加上base参数可以得到十进制下的数,通过相加在用bin操作,即可得到二进制的和。 18 | 19 | ## Solution 20 | 21 | Python 22 | 23 | ```python 24 | class Solution(object): 25 | def addBinary(self, a, b): 26 | """ 27 | :type a: str 28 | :type b: str 29 | :rtype: str 30 | """ 31 | return str(bin(int(a, base=2) + int(b, base=2)))[2:] 32 | ``` -------------------------------------------------------------------------------- /Leetcode/112.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class Solution(object): 9 | def hasPathSum(self, root, sum): 10 | """ 11 | :type root: TreeNode 12 | :type sum: int 13 | :rtype: bool 14 | """ 15 | if not root or (not root.left and not root.right): 16 | return bool(root) and (sum == root.val) 17 | sum -= root.val 18 | return self.hasPathSum(root.left, sum) or self.hasPathSum(root.right, sum) -------------------------------------------------------------------------------- /Leetcode/108.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class Solution(object): 9 | def sortedArrayToBST(self, nums): 10 | """ 11 | :type nums: List[int] 12 | :rtype: TreeNode 13 | """ 14 | if not nums: 15 | return 16 | mid = len(nums) / 2 17 | root = TreeNode(nums[mid]) 18 | root.left = self.sortedArrayToBST(nums[:mid]) 19 | root.right = self.sortedArrayToBST(nums[mid:]) 20 | return root -------------------------------------------------------------------------------- /Leetcode/14.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def longestCommonPrefix(self, strs): 3 | """ 4 | :type strs: List[str] 5 | :rtype: str 6 | """ 7 | if strs == []: 8 | return "" 9 | strs = sorted(strs) 10 | str1 = strs[0] 11 | str2 = strs[-1] 12 | ret = 0 13 | for i in range(min(len(str1), len(str2))): 14 | if str1[i] == str2[i]: 15 | ret += 1 16 | else: 17 | break 18 | 19 | return str1[:ret] 20 | 21 | 22 | solution = Solution() 23 | print(solution.longestCommonPrefix(['a', 'b'])) 24 | 25 | -------------------------------------------------------------------------------- /Leetcode/203.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | # class ListNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.next = None 6 | 7 | class Solution(object): 8 | def removeElements(self, head, val): 9 | """ 10 | :type head: ListNode 11 | :type val: int 12 | :rtype: ListNode 13 | """ 14 | node = ListNode(None) 15 | node.next = head 16 | p = node 17 | while p.next: 18 | if p.next.val != val: 19 | p = p.next 20 | else: 21 | p.next = p.next.next 22 | return node.next -------------------------------------------------------------------------------- /Leetcode/83.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | # class ListNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.next = None 6 | 7 | class Solution(object): 8 | def deleteDuplicates(self, head): 9 | """ 10 | :type head: ListNode 11 | :rtype: ListNode 12 | """ 13 | p = head 14 | if not head or not head.next: 15 | return head 16 | while head: 17 | if head.next and head.val == head.next.val: 18 | head.next = head.next.next 19 | else: 20 | head = head.next 21 | 22 | return p -------------------------------------------------------------------------------- /Leetcode/167.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def twoSum(self, numbers, target): 3 | """ 4 | :type numbers: List[int] 5 | :type target: int 6 | :rtype: List[int] 7 | """ 8 | if not numbers: 9 | return None 10 | i = 0 11 | j = len(numbers) - 1 12 | while i < j: 13 | s = numbers[i] + numbers[j] 14 | if s == target: 15 | return [i+1, j+1] 16 | elif s < target: 17 | i += 1 18 | else: 19 | j -= 1 20 | 21 | 22 | 23 | solution = Solution() 24 | 25 | print solution.twoSum([2,7,11,15], 9) -------------------------------------------------------------------------------- /Leetcode/100.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class Solution(object): 9 | def isSameTree(self, p, q): 10 | """ 11 | :type p: TreeNode 12 | :type q: TreeNode 13 | :rtype: bool 14 | """ 15 | if not p and not q: 16 | return True 17 | if not p or not q: 18 | return False 19 | if p.val != q.val: 20 | return False 21 | return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right) -------------------------------------------------------------------------------- /Leetcode/345.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def reverseVowels(self, s): 3 | """ 4 | :type s: str 5 | :rtype: str 6 | """ 7 | s = list(s) 8 | i, j = 0, len(s) - 1 9 | while i < j: 10 | if s[i] in 'aeiouAEIOU' and s[j] in 'aeiouAEIOU': 11 | s[i], s[j] = s[j], s[i] 12 | i += 1 13 | j -= 1 14 | elif s[i] not in 'aeiouAEIOU': 15 | i += 1 16 | elif s[j] not in 'aeiouAEIOU': 17 | j -= 1 18 | return ''.join(s) 19 | 20 | solution = Solution() 21 | 22 | print solution.reverseVowels("hello") -------------------------------------------------------------------------------- /Leetcode/101.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class Solution(object): 9 | def check(self, p, q): 10 | if not p and not q: 11 | return True 12 | if not p or not q: 13 | return False 14 | if p.val == q.val: 15 | return self.check(p.right, q.left) and self.check(p.left, q.right) 16 | 17 | def isSymmetric(self, root): 18 | """ 19 | :type root: TreeNode 20 | :rtype: bool 21 | """ 22 | return self.check(root, root) -------------------------------------------------------------------------------- /Leetcode/404.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class Solution(object): 9 | def sumOfLeftLeaves(self, root): 10 | """ 11 | :type root: TreeNode 12 | :rtype: int 13 | """ 14 | if not root: 15 | return 0 16 | elif root.left and root.left.left == None and root.left.right == None: 17 | return root.left.val + self.sumOfLeftLeaves(root.right) 18 | else: 19 | return self.sumOfLeftLeaves(root.left) + self.sumOfLeftLeaves(root.right) -------------------------------------------------------------------------------- /125.md: -------------------------------------------------------------------------------- 1 | # 125. Valid Palindrome 2 | 3 | ## Intro 4 | 5 | Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases. 6 | 7 | For example, 8 | 9 | `"A man, a plan, a canal: Panama"` is a palindrome. 10 | 11 | `"race a car"` is not a palindrome. 12 | 13 | 14 | ## Think 15 | 16 | 判断是否为回文。这里只考虑字符串中的字母和数字,且忽略大小写,所以先对字符串进行处理。 17 | 18 | ## Solution 19 | 20 | Python 21 | 22 | ```python 23 | class Solution(object): 24 | def isPalindrome(self, s): 25 | """ 26 | :type s: str 27 | :rtype: bool 28 | """ 29 | s = [c for c in s.lower() if c.isalnum()] 30 | return s == s[::-1] 31 | ``` -------------------------------------------------------------------------------- /14.md: -------------------------------------------------------------------------------- 1 | # 14. Longest Common Prefix 2 | 3 | ## Intro 4 | 5 | Write a function to find the longest common prefix string amongst an array of strings. 6 | 7 | ## Think 8 | 9 | 一个一个比较 10 | 11 | ## Solution 12 | 13 | Python 14 | 15 | ```python 16 | class Solution(object): 17 | def longestCommonPrefix(self, strs): 18 | """ 19 | :type strs: List[str] 20 | :rtype: str 21 | """ 22 | if strs == []: 23 | return '' 24 | for i in range(len(strs[0])): 25 | for str in strs: 26 | if len(str) <= i or str[i] != strs[0][i]: 27 | return strs[0][:i] 28 | return strs[0] 29 | ``` -------------------------------------------------------------------------------- /172.md: -------------------------------------------------------------------------------- 1 | # 172. Factorial Trailing Zeroes 2 | 3 | ## Intro 4 | 5 | Given an integer n, return the number of trailing zeroes in n!. 6 | 7 | #### Note 8 | 9 | Your solution should be in logarithmic time complexity. 10 | 11 | ## Thinking 12 | 13 | 如果用死方法先求n!再循环除10肯定会超时,那么需要想一个稍微好点的方法。如果尾数有0,那么肯定是由2和5这两个因子相乘得来的。根据数学知识,log2(n)肯定大于log5(n),所以其实就是求log5(n)。 14 | 15 | ## Solution 16 | 17 | Python 18 | 19 | 20 | ```python 21 | class Solution(object): 22 | def trailingZeroes(self, n): 23 | """ 24 | :type n: int 25 | :rtype: int 26 | """ 27 | ret = 0 28 | while n: 29 | ret += n/5 30 | n /= 5 31 | return ret 32 | ``` -------------------------------------------------------------------------------- /217.md: -------------------------------------------------------------------------------- 1 | #217. Contains Duplicate 2 | 3 | ## Intro 4 | 5 | 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. 6 | 7 | 8 | ## Thinking 9 | 10 | 乍一看好像有点类似以前做的用异或来求数组中个数为1的元素,这里是要判断数组中是否有重复的。这里有个小技巧,使用`set`函数。判断`set(nums)`的长度是否和`nums`一样。因为set集合里每个元素都只出现一次,所以很容易判断出是否包含重复元素。 11 | 12 | ## Solution 13 | 14 | Python 15 | 16 | ```python 17 | class Solution(object): 18 | def containsDuplicate(self, nums): 19 | """ 20 | :type nums: List[int] 21 | :rtype: bool 22 | """ 23 | return len(set(nums)) != len(nums) 24 | ``` -------------------------------------------------------------------------------- /169.md: -------------------------------------------------------------------------------- 1 | # 169. Majority Element 2 | 3 | ## Intro 4 | 5 | Given an array of size n, find the majority element. The majority element is the element that appears more than `⌊ n/2 ⌋` times. 6 | 7 | You may assume that the array is non-empty and the majority element always exist in the array. 8 | 9 | 10 | 11 | 12 | ## Thinking 13 | 14 | 这里还是用set来降低时间。主要需要思考的是对下界的考虑。 15 | 16 | ## Solution 17 | 18 | Python 19 | 20 | ```python 21 | class Solution(object): 22 | def majorityElement(self, nums): 23 | """ 24 | :type nums: List[int] 25 | :rtype: int 26 | """ 27 | for i in set(nums): 28 | if nums.count(i) >= len(nums) / 2 + 1: 29 | return i 30 | ``` -------------------------------------------------------------------------------- /Leetcode/235.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class Solution(object): 9 | def lowestCommonAncestor(self, root, p, q): 10 | """ 11 | :type root: TreeNode 12 | :type p: TreeNode 13 | :type q: TreeNode 14 | :rtype: TreeNode 15 | """ 16 | 17 | node = root 18 | 19 | while node: 20 | if node.val > p.val and node.val > q.val: 21 | node = node.left 22 | elif node.val < p.val and node.val < q.val: 23 | node = node.right 24 | else: 25 | return node -------------------------------------------------------------------------------- /Leetcode/8.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def myAtoi(self, str): 3 | """ 4 | :type str: str 5 | :rtype: int 6 | """ 7 | str = str.strip() 8 | neg = 1 9 | if str == '': 10 | return 0 11 | if str and (str[0]=='+' or str[0] == '-'): 12 | if str[0] == '-': 13 | neg = -1 14 | str = str[1:] 15 | ret = '' 16 | for c in str: 17 | if c.isdigit(): 18 | ret += c 19 | else: 20 | break 21 | if not ret: 22 | return 0 23 | return max(min(int(ret) * neg, 2**31-1), -2**31) 24 | 25 | solution = Solution() 26 | 27 | print(solution.myAtoi(' -42')) 28 | -------------------------------------------------------------------------------- /234.md: -------------------------------------------------------------------------------- 1 | # 234. Palindrome Linked List 2 | 3 | ## Intro 4 | 5 | Given a singly linked list, determine if it is a palindrome. 6 | 7 | ## Think 8 | 9 | 想到一种方法是将链表转化为list,再判断list的逆序是否和原来一样。 10 | 11 | ## Solution 12 | 13 | Python 14 | 15 | ```python 16 | # Definition for singly-linked list. 17 | # class ListNode(object): 18 | # def __init__(self, x): 19 | # self.val = x 20 | # self.next = None 21 | 22 | class Solution(object): 23 | def isPalindrome(self, head): 24 | """ 25 | :type head: ListNode 26 | :rtype: bool 27 | """ 28 | vals = [] 29 | while head: 30 | vals.append(head.val) 31 | head = head.next 32 | return vals == vals[::-1] 33 | ``` -------------------------------------------------------------------------------- /137.md: -------------------------------------------------------------------------------- 1 | # 137. Single Number II 2 | 3 | ## Intro 4 | 5 | Given an array of integers, every element appears three times except for one. Find that single one. 6 | 7 | ### Note 8 | 9 | Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? 10 | 11 | ## Thinking 12 | 13 | [136.Single Number](136.md)用到的是位运算,这里的常规方法应该也是用位运算。因为是每个元素出现3次, 所以不能用二进制,可以考虑构造三进制。当然,这里也有个独特的简单思路,那就是用集合。对集合以后的元素求和,再乘上3与原始的集合的和相减,会发现结果就是两倍的single one。 14 | 15 | ## Solution 16 | 17 | Python 18 | 19 | ```python 20 | class Solution(object): 21 | def singleNumber(self, nums): 22 | """ 23 | :type nums: List[int] 24 | :rtype: int 25 | """ 26 | s= set(nums) 27 | return (sum(s)*3 -sum(nums))/2 28 | ``` -------------------------------------------------------------------------------- /Leetcode/278.py: -------------------------------------------------------------------------------- 1 | # The isBadVersion API is already defined for you. 2 | # @param version, an integer 3 | # @return a bool 4 | # def isBadVersion(version): 5 | 6 | def isBadVersion(version): 7 | if version >= 4: 8 | return True 9 | else: 10 | return False 11 | 12 | 13 | class Solution(object): 14 | def firstBadVersion(self, n): 15 | """ 16 | :type n: int 17 | :rtype: int 18 | """ 19 | low, high = 1, n 20 | while low < high: 21 | mid = low + (high - low) / 2 22 | if isBadVersion(mid): 23 | high = mid 24 | else: 25 | low = mid + 1 26 | 27 | return high 28 | 29 | solution = Solution() 30 | 31 | print solution.firstBadVersion(5) -------------------------------------------------------------------------------- /Leetcode/437.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class Solution(object): 9 | def pathSum(self, root, sum): 10 | """ 11 | :type root: TreeNode 12 | :type sum: int 13 | :rtype: int 14 | """ 15 | if not root: 16 | return 0 17 | 18 | return self.dfs(root, sum) + self.pathSum(root.left, sum) + self.pathSum(root.right, sum) 19 | 20 | def dfs(self, root, sum): 21 | if not root: 22 | return 0 23 | sum -= root.val 24 | 25 | return (1 if sum == 0 else 0) + self.dfs(root.left, sum) + self.dfs(root.right, sum) 26 | -------------------------------------------------------------------------------- /Leetcode/994.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def orangesRotting(self, grid): 3 | """ 4 | :type grid: List[List[int]] 5 | :rtype: int 6 | """ 7 | row = len(grid) 8 | col = len(grid[0]) 9 | 10 | fresh = {(i, j) for i in range(row) for j in range(col) if grid[i][j] == 1} 11 | rot = {(i, j) for i in range(row) for j in range(col) if grid[i][j] == 2} 12 | 13 | time = 0 14 | 15 | while fresh: 16 | if not rot: 17 | return -1 18 | rot = {(i+di, j+dj) for i, j in rot 19 | for di, dj in [(0, 1), (0, -1), (1, 0), (-1, 0)] 20 | if (i+di, j+dj) in fresh} 21 | fresh -= rot 22 | time += 1 23 | return time -------------------------------------------------------------------------------- /153.md: -------------------------------------------------------------------------------- 1 | # 153. Find Minimum in Rotated Sorted Array 2 | 3 | ## Intro 4 | 5 | Suppose a sorted array is rotated at some pivot unknown to you beforehand. 6 | 7 | (i.e., `0 1 2 4 5 6 7` might become `4 5 6 7 0 1 2`). 8 | 9 | Find the minimum element. 10 | 11 | You may assume no duplicate exists in the array. 12 | 13 | ## Thinking 14 | 15 | 选取数组中最小的数,第一反应用min,过是过了,但太慢了。根据题目,考虑到他是排好序的,所以我想到了从后往前遍历进行判断。 16 | 17 | ## Solution 18 | 19 | Python 20 | 21 | ```python 22 | class Solution(object): 23 | def findMin(self, nums): 24 | """ 25 | :type nums: List[int] 26 | :rtype: int 27 | """ 28 | for i in xrange(len(nums)-1, 0, -1): 29 | if nums[i] < nums[i-1]: 30 | return nums[i] 31 | return nums[0] 32 | ``` -------------------------------------------------------------------------------- /58.md: -------------------------------------------------------------------------------- 1 | # 58. Length of Last Word 2 | 3 | ## Intro 4 | 5 | Given a string s consists of upper/lower-case alphabets and empty space characters `' '`, return the length of last word in the string. 6 | 7 | If the last word does not exist, return 0. 8 | 9 | ####Note 10 | 11 | A word is defined as a character sequence consists of non-space characters only. 12 | 13 | For example, 14 | Given `s` = `"Hello World"`, 15 | 16 | return `5`. 17 | 18 | ## Thinking 19 | 20 | 使用split函数可以分片,很容易求出结果。 21 | 22 | ## Solution 23 | 24 | Python 25 | 26 | ```python 27 | class Solution(object): 28 | def lengthOfLastWord(self, s): 29 | """ 30 | :type s: str 31 | :rtype: int 32 | """ 33 | return len(s.split()[-1]) if len(s.split()) != 0 else 0 34 | ``` -------------------------------------------------------------------------------- /Leetcode/290.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def wordPattern(self, pattern, str): 3 | """ 4 | :type pattern: str 5 | :type str: str 6 | :rtype: bool 7 | """ 8 | str = str.split() 9 | 10 | d = {} 11 | 12 | if len(set(pattern)) != len(set(str)) or len(pattern) != len(str): 13 | return False 14 | 15 | for i in range(len(pattern)): 16 | if pattern[i] not in d: 17 | d[pattern[i]] = str[i] 18 | elif d[pattern[i]] != str[i]: 19 | return False 20 | return True 21 | 22 | # return list(map(pattern.index, pattern)) == list(map(str.index, str)) 23 | 24 | 25 | solution = Solution() 26 | print solution.wordPattern("aba", "cat cat cat dog") -------------------------------------------------------------------------------- /Leetcode/38.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | 3 | def countAndSay(self, n): 4 | """ 5 | :type n: int 6 | :rtype: str 7 | """ 8 | 9 | prev_person = '1' 10 | for i in range(1, n): 11 | next_person, num, count = '', prev_person[0], 1 12 | for j in range(1, len(prev_person)): 13 | if prev_person[j] == num: 14 | count += 1 15 | else: 16 | next_person += str(count) + num 17 | num = prev_person[j] 18 | count = 1 19 | next_person += str(count) + num 20 | prev_person = next_person 21 | return prev_person 22 | 23 | 24 | solution = Solution() 25 | 26 | print solution.countAndSay(2) 27 | -------------------------------------------------------------------------------- /46.md: -------------------------------------------------------------------------------- 1 | # 46. Permutations 2 | 3 | ## Intro 4 | 5 | Given a collection of **distinct** numbers, return all possible permutations. 6 | 7 | For example, 8 | 9 | `[1,2,3]` have the following permutations: 10 | 11 | ``` 12 | [ 13 | [1,2,3], 14 | [1,3,2], 15 | [2,1,3], 16 | [2,3,1], 17 | [3,1,2], 18 | [3,2,1] 19 | ] 20 | ``` 21 | 22 | ## Thinking 23 | 24 | 求数组元素的全部排列组合。这里有一种trick是将第一个值插入到剩余的数组中,同时剩余的数组递归的重复刚才的操作。最终可以得到全排。 25 | 26 | ## Solution 27 | 28 | Python 29 | 30 | ```python 31 | class Solution(object): 32 | def permute(self, nums): 33 | """ 34 | :type nums: List[int] 35 | :rtype: List[List[int]] 36 | """ 37 | return nums and [p[:i] + [nums[0]] + p[i:] for p in self.permute(nums[1:]) for i in range(len(nums))] or [[]] 38 | ``` -------------------------------------------------------------------------------- /Leetcode/111.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class Solution(object): 9 | 10 | def minDepth(self, root): 11 | """ 12 | :type root: TreeNode 13 | :rtype: int 14 | """ 15 | if root: 16 | if root.right and root.left: 17 | return 1 + min(self.minDepth(root.right), self.minDepth(root.left)) 18 | elif root.right: 19 | return 1 + self.minDepth(root.right) 20 | elif root.left: 21 | return 1 + self.minDepth(root.left) 22 | else: 23 | return 1 24 | else: 25 | return 0 -------------------------------------------------------------------------------- /Leetcode/448.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def findDisappearedNumbers(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: List[int] 6 | """ 7 | # d = {} 8 | # 9 | # for num in nums: 10 | # d[num] = 1 11 | # 12 | # ret = [] 13 | # 14 | # for num in range(1, len(nums)+1): 15 | # if num not in d: 16 | # ret.append(num) 17 | # 18 | # return ret 19 | 20 | for i in range(len(nums)): 21 | if nums[abs(nums[i]) - 1] > 0: 22 | nums[abs(nums[i]) - 1] *= -1 23 | 24 | return [i for i in range(1, len(nums)+1) if nums[i-1] > 0] 25 | 26 | 27 | 28 | solution = Solution() 29 | print solution.findDisappearedNumbers([1, 1, 1]) -------------------------------------------------------------------------------- /27.md: -------------------------------------------------------------------------------- 1 | # 27. Remove Element 2 | 3 | ## Intro 4 | 5 | Given an array and a value, remove all instances of that value in place and return the new length. 6 | 7 | The order of elements can be changed. It doesn't matter what you leave beyond the new length. 8 | 9 | ## Thinking 10 | 11 | 题目中有个细节`in place`, 刚开始没注意到,写出了`len(nums) - nums.count(val)`这个错误代码。这题是要对原list进行删除,并返回长度。正确的删除是关键,这里使用remove函数。remove函数移除列表中某个值的第一个匹配项,那么只要一直进行删除,直到没有这个元素。 12 | 13 | ## Solution 14 | 15 | Python 16 | 17 | ```python 18 | class Solution(object): 19 | def removeElement(self, nums, val): 20 | """ 21 | :type nums: List[int] 22 | :type val: int 23 | :rtype: int 24 | """ 25 | for i in range(nums.count(val)): 26 | nums.remove(val) 27 | return len(nums) 28 | ``` 29 | -------------------------------------------------------------------------------- /53.md: -------------------------------------------------------------------------------- 1 | # 53. Maximum Subarray 2 | 3 | ## Intro 4 | 5 | Find the contiguous subarray within an array (containing at least one number) which has the largest sum. 6 | 7 | For example, given the array `[-2,1,-3,4,-1,2,1,-5,4]`, 8 | the contiguous subarray `[4,-1,2,1]` has the largest sum = `6`. 9 | 10 | ## Thinking 11 | 12 | 最大子序列,这里有一个细节要考虑,就是至少要选择一个数,所以存在全为负的数列中,还是会挑选一个值。 13 | 14 | ## Solution 15 | 16 | Python 17 | 18 | ```python 19 | class Solution(object): 20 | def maxSubArray(self, nums): 21 | """ 22 | :type nums: List[int] 23 | :rtype: int 24 | """ 25 | maxSub = nums[0] 26 | temp = 0 27 | for i in nums: 28 | temp += i 29 | maxSub = max(temp, maxSub) 30 | temp = max(0, temp) 31 | return maxSub 32 | ``` -------------------------------------------------------------------------------- /119.md: -------------------------------------------------------------------------------- 1 | # 119. Pascal's Triangle II 2 | 3 | ## Intro 4 | 5 | Given an index k, return the ![](https://www.zhihu.com/equation?tex=k%5E%7Bth%7D%20) row of the Pascal's triangle. 6 | 7 | For example, given k = 3, 8 | Return `[1,3,3,1]`. 9 | 10 | ## Thinking 11 | 12 | 就是将[118. Pascal's Triangle](https://github.com/xinqiu/My-LeetCode-Notes/blob/master/118.md)的前面一部分抽出来。同样的思路,利用列表生成器巧妙的将[0]加在上面一列前和后,然后进行zip求和。 13 | 14 | ## Solution 15 | 16 | Python 17 | 18 | 19 | ```python 20 | class Solution(object): 21 | def getRow(self, rowIndex): 22 | """ 23 | :type rowIndex: int 24 | :rtype: List[int] 25 | """ 26 | list = [1] 27 | while rowIndex: 28 | list = [sum(i) for i in zip([0] + list, list + [0])] 29 | rowIndex -= 1 30 | return list 31 | ``` -------------------------------------------------------------------------------- /Leetcode/257.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class Solution(object): 9 | def binaryTreePaths(self, root): 10 | """ 11 | :type root: TreeNode 12 | :rtype: List[str] 13 | """ 14 | if not root: 15 | return [] 16 | if not root.left and not root.right: 17 | return [str(root.val)] 18 | 19 | paths = [] 20 | 21 | if root.left: 22 | for p in self.binaryTreePaths(root.left): 23 | paths.append(str(root.val) + '->' + p) 24 | if root.right: 25 | for p in self.binaryTreePaths(root.right): 26 | paths.append(str(root.val) + '->' + p) 27 | return paths -------------------------------------------------------------------------------- /168.md: -------------------------------------------------------------------------------- 1 | #168. Excel Sheet Column Title 2 | 3 | ## Intro 4 | 5 | Given a positive integer, return its corresponding column title as appear in an Excel sheet. 6 | 7 | For example: 8 | 9 | ``` 10 | 1 -> A 11 | 2 -> B 12 | 3 -> C 13 | ... 14 | 26 -> Z 15 | 27 -> AA 16 | 28 -> AB 17 | ``` 18 | 19 | ## Thinking 20 | 21 | 其实这题就是进制转换,将十进制转换为二十六进制。每一位的处理方式是一样的,都是利用`chr((n - 1) % 26 + 65)` 得到字母。对于进位的考虑,大致思路肯定是用`n / 26`,但这里会出现一个问题,当`n`为26时,答案会变成`AZ`,所以进位的计算应该为`(n - 1) / 26`。 22 | 23 | ## Solution 24 | 25 | Python 26 | 27 | ```python 28 | class Solution(object): 29 | def convertToTitle(self, n): 30 | """ 31 | :type n: int 32 | :rtype: str 33 | """ 34 | s = '' 35 | while n > 0: 36 | s = chr(65 + (n - 1) % 26) + s 37 | n = (n - 1) / 26 38 | return s 39 | ``` 40 | -------------------------------------------------------------------------------- /219.md: -------------------------------------------------------------------------------- 1 | # 219. Contains Duplicate II 2 | 3 | ## Intro 4 | 5 | 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. 6 | 7 | ## Thinking 8 | 9 | 判断是否存在相同的元素,它们的索引差小于等于k.用一个字典来保存下标,这样再发现重复的元素时,用这个下标减去字典中前一次出现的下标就能得到下标查。 10 | 11 | ## Solution 12 | 13 | Python 14 | 15 | ```python 16 | class Solution(object): 17 | def containsNearbyDuplicate(self, nums, k): 18 | """ 19 | :type nums: List[int] 20 | :type k: int 21 | :rtype: bool 22 | """ 23 | tmpDict = {} 24 | for i in xrange(len(nums)): 25 | index = tmpDict.get(nums[i]) 26 | if index >= 0 and i - index <= k: 27 | return True 28 | tmpDict[nums[i]] = i 29 | return False 30 | ``` 31 | -------------------------------------------------------------------------------- /189.md: -------------------------------------------------------------------------------- 1 | # 189. Rotate Array 2 | 3 | ## Intro 4 | 5 | Rotate an array of *n* elements to the right by *k* steps. 6 | 7 | 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]`. 8 | 9 | #### Note 10 | 11 | Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem. 12 | 13 | 14 | ## Think 15 | 16 | 有点像将list首尾链接,拼接成循环list,然后在向右偏移k,也就是向左偏移len(nums) - k。之前一直卡在 `Do not return anything, modify nums in-place instead.`原来是多写了`return`. 17 | 18 | ## Solution 19 | 20 | Python 21 | 22 | ```python 23 | class Solution(object): 24 | def rotate(self, nums, k): 25 | """ 26 | :type nums: List[int] 27 | :type k: int 28 | :rtype: void Do not return anything, modify nums in-place instead. 29 | """ 30 | k = k % len(nums) 31 | nums[:] = nums[-k:] + nums[:-k] 32 | ``` -------------------------------------------------------------------------------- /Leetcode/面试题57 - II.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def findContinuousSequence(self, target): 3 | """ 4 | :type target: int 5 | :rtype: List[List[int]] 6 | """ 7 | 8 | # nums = list(range(1, target)) 9 | # d = {} 10 | # ret = [] 11 | # for i in range(target): 12 | # if i*(i+1)/2 - target in d: 13 | # ret.append(nums[d[i*(i+1)/2-target]: i]) 14 | # d[i*(i+1)/2] = i 15 | # 16 | # return ret 17 | 18 | s = [(1 + i) * i / 2 for i in range(target)] 19 | nums = list(range(1, target)) 20 | d = {} 21 | ret = [] 22 | for i, v in enumerate(s): 23 | if v - target in d: 24 | ret.append(nums[d[v - target]: i]) 25 | d[v] = i 26 | 27 | return ret 28 | 29 | solution = Solution() 30 | 31 | print solution.findContinuousSequence(9) -------------------------------------------------------------------------------- /26.md: -------------------------------------------------------------------------------- 1 | # 26. Remove Duplicates from Sorted Array 2 | 3 | ## Intro 4 | 5 | Given a sorted array, remove the duplicates in place such that each element appear only once and return the new length. 6 | 7 | Do not allocate extra space for another array, you must do this in place with constant memory. 8 | 9 | For example, 10 | Given input array nums = `[1,1,2]`, 11 | 12 | Your function should return length = `2`, with the first two elements of nums being `1` and `2` respectively. It doesn't matter what you leave beyond the new length. 13 | 14 | ## Thinking 15 | 16 | 使用set集合可以很方便的做到,这里有两个细节要注意,首先是要用sorted进行排序,另外不能简单赋值,这里需要用到深度拷贝。 17 | 18 | ## Solution 19 | 20 | Python 21 | 22 | ```python 23 | class Solution(object): 24 | def removeDuplicates(self, nums): 25 | """ 26 | :type nums: List[int] 27 | :rtype: int 28 | """ 29 | nums[:] = sorted(set(nums)) 30 | return len(nums) 31 | ``` -------------------------------------------------------------------------------- /Leetcode/118.py: -------------------------------------------------------------------------------- 1 | # class Solution(object): 2 | # def generate(self, numRows): 3 | # """ 4 | # :type numRows: int 5 | # :rtype: List[List[int]] 6 | # """ 7 | # 8 | # ret = [[1 for i in range(1, numRows+1) if i <= j] for j in range(1, numRows+1)] 9 | # 10 | # for i in range(2, numRows): 11 | # for j in range(1, i): 12 | # ret[i][j] = ret[i-1][j-1]+ret[i-1][j] 13 | # 14 | # return ret 15 | 16 | class Solution(object): 17 | def generate(self, numRows): 18 | """ 19 | :type numRows: int 20 | :rtype: List[List[int]] 21 | """ 22 | 23 | if numRows == 0: 24 | return [] 25 | ret = [[1]] 26 | while len(ret) < numRows: 27 | ret.append([a+b for a, b in zip([0]+ret[-1], ret[-1]+[0])]) 28 | return ret 29 | 30 | 31 | solution = Solution() 32 | 33 | print solution.generate(0) -------------------------------------------------------------------------------- /Leetcode/119.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def getRow(self, rowIndex): 3 | """ 4 | :type rowIndex: int 5 | :rtype: List[int] 6 | """ 7 | rowIndex = rowIndex + 1 8 | ret = [[1 for i in range(1, rowIndex + 1) if i <= j] for j in range(1, rowIndex + 1)] 9 | 10 | for i in range(2, rowIndex): 11 | for j in range(1, i): 12 | ret[i][j] = ret[i - 1][j - 1] + ret[i - 1][j] 13 | 14 | return ret[-1] 15 | 16 | class Solution(object): 17 | def getRow(self, rowIndex): 18 | """ 19 | :type rowIndex: int 20 | :rtype: List[int] 21 | """ 22 | if rowIndex == 0: 23 | return [1] 24 | rowIndex += 1 25 | ret = [1] 26 | while len(ret) < rowIndex: 27 | ret = [a+b for a, b in zip([0]+ret, ret+[0])] 28 | return ret 29 | 30 | solution = Solution() 31 | 32 | print solution.getRow(0) -------------------------------------------------------------------------------- /378.md: -------------------------------------------------------------------------------- 1 | # 378. Kth Smallest Element in a Sorted Matrix 2 | 3 | ## Intro 4 | 5 | Given a n x n matrix where each of the rows and columns are sorted in ascending order, find the kth smallest element in the matrix. 6 | 7 | Note that it is the kth smallest element in the sorted order, not the kth distinct element. 8 | 9 | Example: 10 | 11 | ``` 12 | matrix = [ 13 | [ 1, 5, 9], 14 | [10, 11, 13], 15 | [12, 13, 15] 16 | ], 17 | k = 8, 18 | 19 | return 13. 20 | ``` 21 | 22 | #### Note 23 | 24 | You may assume k is always valid, 1 ≤ k ≤ n^2. 25 | 26 | ## Thinking 27 | 28 | 简单点的方法就是讲matrix变成一维的array,然后进行排序。 29 | 30 | ## Solution 31 | 32 | Python 33 | 34 | ```python 35 | class Solution(object): 36 | def kthSmallest(self, matrix, k): 37 | """ 38 | :type matrix: List[List[int]] 39 | :type k: int 40 | :rtype: int 41 | """ 42 | return sorted([y for x in matrix for y in x])[k-1] 43 | ``` -------------------------------------------------------------------------------- /Leetcode/206.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | # class ListNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.next = None 6 | 7 | # class Solution(object): 8 | # def reverseList(self, head): 9 | # """ 10 | # :type head: ListNode 11 | # :rtype: ListNode 12 | # """ 13 | # pre = None 14 | # cur = head 15 | # 16 | # while cur: 17 | # t = cur.next 18 | # cur.next = pre 19 | # pre = cur 20 | # cur = t 21 | # 22 | # return pre 23 | 24 | 25 | class Solution(object): 26 | def reverseList(self, head): 27 | """ 28 | :type head: ListNode 29 | :rtype: ListNode 30 | """ 31 | if not head or not head.next: 32 | return head 33 | t = self.reverseList(head.next) 34 | head.next.next = head 35 | head.next = None 36 | return t -------------------------------------------------------------------------------- /104.md: -------------------------------------------------------------------------------- 1 | #104. Maximum Depth of Binary Tree 2 | 3 | ## Intro 4 | 5 | Given a binary tree, find its maximum depth. 6 | 7 | The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. 8 | 9 | ## Thinking 10 | 11 | 看完题目,不难想到用递归求左右子树的最大深度。首先判断根是否为空,为空则返回0。下面要考虑的是根不为空的情况。因为每次递归返回的都是左右子树的最大深度,所以用max函数来比较深度最为合适,因为是递归,所以在返回时不能忘了在每次递归结果需要加1。 12 | 13 | 14 | ## Solution 15 | Python 16 | 17 | ```python 18 | # Definition for a binary tree node. 19 | # class TreeNode(object): 20 | # def __init__(self, x): 21 | # self.val = x 22 | # self.left = None 23 | # self.right = None 24 | 25 | class Solution(object): 26 | def maxDepth(self, root): 27 | """ 28 | :type root: TreeNode 29 | :rtype: int 30 | """ 31 | if root == None: 32 | return 0 33 | return max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1 34 | 35 | ``` -------------------------------------------------------------------------------- /263.md: -------------------------------------------------------------------------------- 1 | # 263. Ugly Number 2 | 3 | ## Intro 4 | 5 | Write a program to check whether a given number is an ugly number. 6 | 7 | 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`. 8 | 9 | Note that `1` is typically treated as an ugly number. 10 | 11 | ## Thinking 12 | 13 | 竟然最新想到的是最笨的方法要去算质数,后来想想这样子肯定不行,只好换了一个角度重新思考。这里有个规律,让这个数循环除以2、3、5。如果最后等于1,则是Ugly Number,如果不是,则不是。很好理解,若是这个数只是2或3或5的倍数,那么它不停的除,最后只会等于1。也就是说,这个数的约数也只是2、3、5或者这三个数的倍数。 14 | 15 | ## Solution 16 | 17 | Python 18 | 19 | ```python 20 | class Solution(object): 21 | def isUgly(self, num): 22 | """ 23 | :type num: int 24 | :rtype: bool 25 | """ 26 | if num <= 0: 27 | return False 28 | for x in [2, 3, 5]: 29 | while num % x == 0: 30 | num = num / x 31 | return num == 1 32 | ``` -------------------------------------------------------------------------------- /121.md: -------------------------------------------------------------------------------- 1 | # 121. Best Time to Buy and Sell Stock 2 | 3 | ## Intro 4 | 5 | Say you have an array for which the ith element is the price of a given stock on day i. 6 | 7 | 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. 8 | 9 | ## Think 10 | 11 | 股票买卖问题,其中只能买和卖一次,那么就是要选择在价格最低的时候买,在之后价格最高的时候卖。这里用到的是DP的思想。从左往右遍历,一边寻找最小的值,一边寻找利润最大的值。 12 | 13 | ## Solution 14 | 15 | Python 16 | 17 | ```python 18 | class Solution(object): 19 | def maxProfit(self, prices): 20 | """ 21 | :type prices: List[int] 22 | :rtype: int 23 | """ 24 | 25 | if len(prices) < 2: 26 | return 0 27 | profit = 0 28 | curMin = prices[0] 29 | for i in range(1, len(prices)): 30 | curMin = min(curMin, prices[i]) 31 | profit = max(profit, prices[i] - curMin) 32 | return profit 33 | ``` -------------------------------------------------------------------------------- /389.md: -------------------------------------------------------------------------------- 1 | # 389. Find the Difference 2 | 3 | ## Intro 4 | 5 | Given two strings ***s*** and ***t*** which consist of only lowercase letters. 6 | 7 | String ***t*** is generated by random shuffling string ***s*** and then add one more letter at a random position. 8 | 9 | Find the letter that was added in ***t***. 10 | 11 | #### Example 12 | 13 | ``` 14 | Input: 15 | s = "abcd" 16 | t = "abcde" 17 | 18 | Output: 19 | e 20 | 21 | Explanation: 22 | 'e' is the letter that was added. 23 | ``` 24 | 25 | ## Thinking 26 | 27 | 筛选出两个字符串中不一样的唯一字母。注意,这里关键是只添加一个与众不同的字母,所以就可以考虑到以前类似的数组中筛选出唯一一个不同的数,而方法就是异或。首先需要将字符串转为变成ascii数组,之后只需要对整个数组做异或,最后的结果就是不同的字母的ascii,接着就是转换为字符。因为两个字符串只有一个字符不同,所以其他字符都是成对出现,可以用异或消去。 28 | 29 | ## Solution 30 | 31 | Python 32 | 33 | ```python 34 | class Solution(object): 35 | def findTheDifference(self, s, t): 36 | """ 37 | :type s: str 38 | :type t: str 39 | :rtype: str 40 | """ 41 | return chr(reduce(lambda x, y: x ^ y,map(ord, s + t))) 42 | ``` -------------------------------------------------------------------------------- /Leetcode/121.py: -------------------------------------------------------------------------------- 1 | # class Solution(object): 2 | # def maxProfit(self, prices): 3 | # """ 4 | # :type prices: List[int] 5 | # :rtype: int 6 | # """ 7 | # ret = 0 8 | # 9 | # if len(prices) <= 1: 10 | # return 0 11 | # 12 | # p = 0 13 | # for i in range(1, len(prices)): 14 | # if prices[i] - prices[p] >= ret: 15 | # ret = prices[i] - prices[p] 16 | # elif prices[i] < prices[p]: 17 | # p = i 18 | # else: 19 | # pass 20 | # 21 | # return ret 22 | 23 | class Solution(object): 24 | def maxProfit(self, prices): 25 | """ 26 | :type prices: List[int] 27 | :rtype: int 28 | """ 29 | min_p, max_p = 1e9, 0 30 | for p in prices: 31 | min_p = min(min_p, p) 32 | max_p = max(max_p, p-min_p) 33 | return max_p 34 | 35 | 36 | solution = Solution() 37 | 38 | print solution.maxProfit([7,1,5,3,6,4]) -------------------------------------------------------------------------------- /Leetcode/2.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | class ListNode(object): 3 | def __init__(self, x): 4 | self.val = x 5 | self.next = None 6 | 7 | 8 | class Solution(object): 9 | def addTwoNumbers(self, l1, l2): 10 | """ 11 | :type l1: ListNode 12 | :type l2: ListNode 13 | :rtype: ListNode 14 | """ 15 | n1 = '' 16 | while l1 != None: 17 | n1 = str(l1.val) + n1 18 | l1 = l1.next 19 | 20 | n2 = '' 21 | while l2 != None: 22 | n2 = str(l2.val) + n2 23 | l2 = l2.next 24 | 25 | s = str(int(n1)+int(n2))[::-1] 26 | print(s) 27 | p = ListNode(int(s[0])) 28 | ret = p 29 | for c in s[1:]: 30 | p.next = ListNode(int(c)) 31 | p = p.next 32 | return ret 33 | 34 | 35 | solution = Solution() 36 | 37 | l1 = ListNode(1) 38 | l1.next = ListNode(8) 39 | 40 | l2 = ListNode(0) 41 | 42 | print(solution.addTwoNumbers(l1, l2)) -------------------------------------------------------------------------------- /Leetcode/面试题59 - II.py: -------------------------------------------------------------------------------- 1 | import Queue 2 | 3 | class MaxQueue(object): 4 | 5 | def __init__(self): 6 | self.deque = Queue.deque() 7 | self.m = -1 8 | 9 | 10 | def max_value(self): 11 | """ 12 | :rtype: int 13 | """ 14 | return self.m if self.deque else -1 15 | 16 | 17 | 18 | def push_back(self, value): 19 | """ 20 | :type value: int 21 | :rtype: None 22 | """ 23 | self.m = max(value, self.m) 24 | self.deque.append(value) 25 | 26 | 27 | def pop_front(self): 28 | """ 29 | :rtype: int 30 | """ 31 | if not self.deque: 32 | return -1 33 | ret = self.deque.popleft() 34 | if ret == self.m: 35 | self.m = max(self.deque) if self.deque else -1 36 | return ret 37 | 38 | 39 | # Your MaxQueue object will be instantiated and called as such: 40 | # obj = MaxQueue() 41 | # param_1 = obj.max_value() 42 | # obj.push_back(value) 43 | # param_3 = obj.pop_front() -------------------------------------------------------------------------------- /268.md: -------------------------------------------------------------------------------- 1 | # 268. Missing Number 2 | 3 | ## Intro 4 | 5 | Given an array containing n distinct numbers taken from `0, 1, 2, ..., n`, find the one that is missing from the array. 6 | 7 | For example, 8 | 9 | Given nums = `[0, 1, 3]` return `2`. 10 | 11 | #### Note 12 | 13 | Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity? 14 | 15 | ## Think 16 | 17 | 我想到的思路是找出nums中最大的数n,计算1到n的和,用这个和减去nums中的每个元素,剩下的就是缺少的值。这里有个陷阱就是0。要判断0是否在nums中,如果在,那么缺少的值就是n + 1,如果不在,缺少的就是0. 18 | 19 | 另外我发现Leetcode对求最大数要比求len耗时更少。 20 | 21 | ## Solution 22 | 23 | Python 24 | 25 | ```python 26 | class Solution(object): 27 | def missingNumber(self, nums): 28 | """ 29 | :type nums: List[int] 30 | :rtype: int 31 | """ 32 | n = max(nums) 33 | ret = (1 + n) * n / 2 - sum(nums) 34 | if ret != 0: 35 | return ret 36 | elif 0 in nums: 37 | return n + 1 38 | else: 39 | return 0 40 | ``` -------------------------------------------------------------------------------- /122.md: -------------------------------------------------------------------------------- 1 | # 122. Best Time to Buy and Sell Stock II 2 | 3 | ## Intro 4 | 5 | Say you have an array for which the i^{th} element is the price of a given stock on day i. 6 | 7 | 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). 8 | 9 | ## Think 10 | 11 | 股票买卖问题,是[121](121.md)的升级版。这里允许买卖多次。其实这个比之前的题要简单。有个很简单的思路,就是将所有涨时候的差价求和就是结果。买股票要想赚的最多其实就是只要买它就涨只要卖它就跌。那么获得的最多的利润,就是股价涨之前和之后的差价。 12 | 13 | ## Solution 14 | 15 | Python 16 | 17 | ```python 18 | class Solution(object): 19 | def maxProfit(self, prices): 20 | """ 21 | :type prices: List[int] 22 | :rtype: int 23 | """ 24 | profit = 0 25 | for i in xrange(1, len(prices)): 26 | if prices[i] > prices[i-1]: 27 | profit += (prices[i] - prices[i-1]) 28 | return profit 29 | ``` -------------------------------------------------------------------------------- /345.md: -------------------------------------------------------------------------------- 1 | # 345. Reverse Vowels of a String 2 | 3 | ## Intro 4 | 5 | Write a function that takes a string as input and reverse only the vowels of a string. 6 | 7 | #### Example 1 8 | 9 | Given s = "hello", return "holle". 10 | 11 | ##### Example 2 12 | 13 | Given s = "leetcode", return "leotcede". 14 | 15 | ## Think 16 | 17 | 只让字符串中的元音逆序。那么可以想到的就是首尾一起向中间开始遍历,如果都是元音就交换,不然就继续移动。 18 | 19 | ## Solution 20 | 21 | Python 22 | 23 | ```python 24 | class Solution(object): 25 | def reverseVowels(self, s): 26 | """ 27 | :type s: str 28 | :rtype: str 29 | """ 30 | s = list(s) 31 | i = 0 32 | j = len(s) - 1 33 | while i < j: 34 | if s[i] not in 'aeiouAEIOU': 35 | i += 1 36 | if s[j] not in 'aeiouAEIOU': 37 | j -= 1 38 | if s[i] in 'aeiouAEIOU' and s[j] in 'aeiouAEIOU': 39 | s[i], s[j] = s[j], s[i] 40 | i += 1 41 | j -= 1 42 | return ''.join(s) 43 | ``` -------------------------------------------------------------------------------- /108.md: -------------------------------------------------------------------------------- 1 | # 108. Convert Sorted Array to Binary Search Tree 2 | 3 | ## Intro 4 | 5 | Given an array where elements are sorted in ascending order, convert it to a height balanced BST. 6 | 7 | ## Thinking 8 | 9 | 排序的数组转化为BST。首先根据二叉搜索树的性质,可以知道每个节点的左子树都比这个节点值小,右子树都要比这个节点值大。那么树的根肯定是数组中间的值,接着进行左右子树。会发现,左右子树又可以看成是直接找根的方法。所以这里用递归的思路,可以知道递归的深度为logn。 10 | 11 | ## Solution 12 | 13 | Python 14 | 15 | ```python 16 | # Definition for a binary tree node. 17 | # class TreeNode(object): 18 | # def __init__(self, x): 19 | # self.val = x 20 | # self.left = None 21 | # self.right = None 22 | 23 | class Solution(object): 24 | def sortedArrayToBST(self, nums): 25 | """ 26 | :type nums: List[int] 27 | :rtype: TreeNode 28 | """ 29 | if not nums: 30 | return 31 | mid = len(nums)/2 32 | root = TreeNode(nums[mid]) 33 | root.left = self.sortedArrayToBST(nums[:mid]) 34 | root.right = self.sortedArrayToBST(nums[mid+1:]) 35 | return root 36 | ``` -------------------------------------------------------------------------------- /Leetcode/538.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class Solution(object): 9 | def convertBST(self, root): 10 | """ 11 | :type root: TreeNode 12 | :rtype: TreeNode 13 | """ 14 | # if not root: 15 | # return 16 | # 17 | # def helper(root, t): 18 | # if not root: 19 | # return t 20 | # t = helper(root.right, t) 21 | # root.val += t 22 | # t = helper(root.left, root.val) 23 | # return t 24 | # helper(root, 0) 25 | # return root 26 | self.sum = 0 27 | 28 | def dfs(root): 29 | if not root: return root 30 | dfs(root.right) 31 | self.sum = self.sum + root.val 32 | root.val = self.sum 33 | dfs(root.left) 34 | return root 35 | 36 | return dfs(root) 37 | -------------------------------------------------------------------------------- /111.md: -------------------------------------------------------------------------------- 1 | # 111. Minimum Depth of Binary Tree 2 | 3 | ## Intro 4 | 5 | Given a binary tree, find its minimum depth. 6 | 7 | The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node. 8 | 9 | ## Thinking 10 | 11 | 用迭代来遍历树, 比较左右子树的最小深度。如果子树左右无儿子节点,则返回0, 如果无左节点,则从右节点继续遍历,深度加一,无右节点,则从左节点继续,深度加一。 12 | 13 | ## Solution 14 | 15 | Python 16 | 17 | ```python 18 | # Definition for a binary tree node. 19 | # class TreeNode(object): 20 | # def __init__(self, x): 21 | # self.val = x 22 | # self.left = None 23 | # self.right = None 24 | 25 | class Solution(object): 26 | def minDepth(self, root): 27 | """ 28 | :type root: TreeNode 29 | :rtype: int 30 | """ 31 | if not root: 32 | return 0 33 | if not root.left: 34 | return self.minDepth(root.right) + 1 35 | if not root.right: 36 | return self.minDepth(root.left) + 1 37 | return min(self.minDepth(root.left), self.minDepth(root.right)) + 1 38 | ``` -------------------------------------------------------------------------------- /118.md: -------------------------------------------------------------------------------- 1 | # 118. Pascal's Triangle 2 | 3 | ## Intro 4 | 5 | Given numRows, generate the first numRows of Pascal's triangle. 6 | 7 | For example, given *numRows* = 5, 8 | Return 9 | 10 | ``` 11 | [ 12 | [1], 13 | [1,1], 14 | [1,2,1], 15 | [1,3,3,1], 16 | [1,4,6,4,1] 17 | ] 18 | ``` 19 | 20 | ## Thinking 21 | 22 | 返回一个杨辉三角形的list。首先,杨辉三角形的定义有每个数等于它上方两数之和。每行数字左右对称,由1开始逐渐变大。 23 | 24 | 这里,假设[1]的左右都有[0],每个数等于它上方两数之和,那么可以构造两个list,一个前面添加[0], 一个后面添加[0],那么这两个list相加,得到的包含两个数的和的list就是新的一行,不断迭代,一直迭代到numRows。 25 | 26 | 27 | ## Solution 28 | 29 | Python 30 | 31 | 32 | ```python 33 | class Solution(object): 34 | def generate(self, numRows): 35 | """ 36 | :type numRows: int 37 | :rtype: List[List[int]] 38 | """ 39 | if not numRows: 40 | return [] 41 | list = [[1]] 42 | a = [1] 43 | numRows -= 1 44 | while numRows: 45 | a = [sum(i) for i in zip([0] + a, a + [0])] 46 | list.append(a) 47 | numRows -= 1 48 | return list 49 | ``` 50 | 51 | 52 | -------------------------------------------------------------------------------- /203.md: -------------------------------------------------------------------------------- 1 | # 203. Remove Linked List Elements 2 | 3 | ## Intro 4 | 5 | Remove all elements from a linked list of integers that have value *val*. 6 | 7 | ####Example 8 | 9 | *Given*: 1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6, *val* = 6 10 | 11 | *Return*: 1 --> 2 --> 3 --> 4 --> 5 12 | 13 | ## Think 14 | 15 | 删除一个链表里的特定值。这里的一个技巧是在链表的head前面添加一个节点p,让p.next = head,然后让head指向新增的这个节点。用p指针进行循环右移,判断p.next.val是否等于val。 16 | 17 | ## Solution 18 | 19 | Python 20 | 21 | ```python 22 | # Definition for singly-linked list. 23 | # class ListNode(object): 24 | # def __init__(self, x): 25 | # self.val = x 26 | # self.next = None 27 | 28 | class Solution(object): 29 | def removeElements(self, head, val): 30 | """ 31 | :type head: ListNode 32 | :type val: int 33 | :rtype: ListNode 34 | """ 35 | p = ListNode(0) 36 | p.next, head = head, p 37 | while p.next: 38 | if p.next.val == val: 39 | p.next = p.next.next 40 | else: 41 | p = p.next 42 | return head.next 43 | ``` -------------------------------------------------------------------------------- /326.md: -------------------------------------------------------------------------------- 1 | # 326. Power of Three 2 | 3 | ## Intro 4 | 5 | Given an integer, write a function to determine if it is a power of three. 6 | 7 | #### Follow up 8 | 9 | Could you do it without using any loop / recursion? 10 | 11 | ## Thinking 12 | 13 | 不能用循环和递归,所以就要考虑数学方法。第一感觉是求log3是不是为整数。试了一下,确实过了。接着就是想想有什么更好的方法,看到一个很有想法的方案,使用1162261467。判断1162261467 % n。1162261467是int范围下最大的3的幂,那么只要是3的幂,那么都应该能被整除。 14 | 15 | ## Solution 16 | 17 | Python 18 | 19 | ```python 20 | from math import log 21 | class Solution(object): 22 | 23 | def isPowerOfThree(self, n): 24 | """ 25 | :type n: int 26 | :rtype: bool 27 | """ 28 | if n <= 0: 29 | return False 30 | else: 31 | return abs(log(n,3) - round(log(n, 3))) <= 1e-10 32 | ``` 33 | 34 | Another 35 | ```python 36 | class Solution(object): 37 | def isPowerOfThree(self, n): 38 | """ 39 | :type n: int 40 | :rtype: bool 41 | """ 42 | if n <= 0: 43 | return False 44 | else: 45 | return 1162261467 % n == 0 46 | ``` 47 | 48 | -------------------------------------------------------------------------------- /Leetcode/20.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def isValid(self, s): 3 | """ 4 | :type s: str 5 | :rtype: bool 6 | """ 7 | 8 | m = { 9 | ')': '(', 10 | '}': '{', 11 | ']': '[' 12 | } 13 | stack = [] 14 | 15 | for c in s: 16 | if c == '(' or c == '[' or c == '{': 17 | stack.append(c) 18 | else: 19 | if stack: 20 | if m[c] != stack[-1]: 21 | return False 22 | else: 23 | stack.pop() 24 | else: 25 | return False 26 | if not stack: 27 | return True 28 | else: 29 | return False 30 | 31 | solution = Solution() 32 | print(solution.isValid('(]')) 33 | 34 | ''' 35 | class Solution: 36 | def isValid(self, s): 37 | while '{}' in s or '()' in s or '[]' in s: 38 | s = s.replace('{}', '') 39 | s = s.replace('[]', '') 40 | s = s.replace('()', '') 41 | return s == '' 42 | ''' -------------------------------------------------------------------------------- /383.md: -------------------------------------------------------------------------------- 1 | # 383. Ransom Note 2 | 3 | ## Intro 4 | 5 | Given an arbitrary ransom note string and another string containing letters from all the magazines, write a function that will return true if the ransom note can be constructed from the magazines ; otherwise, it will return false. 6 | 7 | Each letter in the magazine string can only be used once in your ransom note. 8 | 9 | #### Note 10 | 11 | You may assume that both strings contain only lowercase letters. 12 | 13 | ``` 14 | canConstruct("a", "b") -> false 15 | canConstruct("aa", "ab") -> false 16 | canConstruct("aa", "aab") -> true 17 | ``` 18 | 19 | ## Thinking 20 | 21 | 其实就是判断前者是不是被后者包含。可以使用collections.Counter来计数,之后相减做判断。也可以自己用循环进行计数比较。 22 | 23 | ## Solution 24 | 25 | Python 26 | 27 | ```python 28 | class Solution(object): 29 | def canConstruct(self, ransomNote, magazine): 30 | """ 31 | :type ransomNote: str 32 | :type magazine: str 33 | :rtype: bool 34 | """ 35 | for i in set(ransomNote): 36 | if ransomNote.count(i) > magazine.count(i): 37 | return False 38 | return True 39 | ``` -------------------------------------------------------------------------------- /171.md: -------------------------------------------------------------------------------- 1 | #171. Excel Sheet Column Number 2 | 3 | ## Intro 4 | 5 | Related to question [Excel Sheet Column Title](https://github.com/xinqiu/My-LeetCode-Notes/blob/master/168.md) 6 | 7 | Given a column title as appear in an Excel sheet, return its corresponding column number. 8 | 9 | For example: 10 | 11 | ``` 12 | A -> 1 13 | B -> 2 14 | C -> 3 15 | ... 16 | Z -> 26 17 | AA -> 27 18 | AB -> 28 19 | ``` 20 | 21 | ## Thinking 22 | 23 | 和168类似,从左到右递归处理。尝试用reduce来做,一开始有个细节没处理的好,后来参考了一些资料发现一行就能解决问题。 24 | 25 | ## Solution 26 | 27 | Python 28 | 29 | ```python 30 | class Solution(object): 31 | def titleToNumber(self, s): 32 | """ 33 | :type s: str 34 | :rtype: int 35 | """ 36 | ans = 0 37 | for c in s: 38 | ans = (ans + ord(c) - 64) * 26 39 | 40 | return ans / 26 41 | ``` 42 | 43 | 更简洁的 44 | 45 | ```python 46 | class Solution(object): 47 | def titleToNumber(self, s): 48 | """ 49 | :type s: str 50 | :rtype: int 51 | """ 52 | 53 | return reduce(lambda x, y: x * 26 + y,map(lambda x: ord(x) - 64, s)) 54 | ``` -------------------------------------------------------------------------------- /343.md: -------------------------------------------------------------------------------- 1 | # 343. Integer Break 2 | 3 | ## Intro 4 | 5 | Given a positive integer n, break it into the sum of **at least** two positive integers and maximize the product of those integers. Return the maximum product you can get. 6 | 7 | For example, given n = 2, return 1 (2 = 1 + 1); given n = 10, return 36 (10 = 3 + 3 + 4). 8 | 9 | #### Note 10 | 11 | you may assume that n is not less than 2. 12 | 13 | #### Hint 14 | 15 | 1. There is a simple O(n) solution to this problem. 16 | 17 | 2. You may check the breaking results of n ranging from 7 to 10 to discover the regularities. 18 | 19 | ## Think 20 | 21 | 这个偏向于数学题。通过找规律,会发现n分解出越多的3,乘积就越大,关于这个的证明参考这篇文章[liyuanbhu的CSDN专栏](http://blog.csdn.net/liyuanbhu/article/details/51198124)。 22 | 23 | ## Solution 24 | 25 | Python 26 | 27 | ```python 28 | class Solution(object): 29 | def integerBreak(self, n): 30 | """ 31 | :type n: int 32 | :rtype: int 33 | """ 34 | if n == 2: 35 | return 1 36 | if n == 3: 37 | return 2 38 | ret = 1 39 | while n > 4: 40 | ret *= 3 41 | n -= 3 42 | return ret * n 43 | ``` -------------------------------------------------------------------------------- /Leetcode/3.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def lengthOfLongestSubstring(self, s): 3 | """ 4 | :type s: str 5 | :rtype: int 6 | """ 7 | ret = '' 8 | maxlen = 0 9 | for c in s: 10 | if c not in ret: 11 | ret += c 12 | else: 13 | ret = ret[ret.index(c)+1:] 14 | ret += c 15 | # for i in range(len(ret)): 16 | # if len(set(ret[i:])) == len(ret[i:]): 17 | # ret = ret[i:] 18 | # break 19 | if len(ret) >= maxlen: 20 | maxlen = len(ret) 21 | return maxlen 22 | 23 | def lengthOfLongestSubstring1(self, s): 24 | l = [] 25 | ret = [] 26 | for c in s: 27 | if c not in l: 28 | l.append(c) 29 | else: 30 | ret.append(len(l)) 31 | l = l[l.index(c)+1:] 32 | l.append(c) 33 | ret.append(len(l)) 34 | return max(ret) if ret else 0 35 | 36 | 37 | 38 | solution = Solution() 39 | 40 | print(solution.lengthOfLongestSubstring('dcdd')) -------------------------------------------------------------------------------- /199.md: -------------------------------------------------------------------------------- 1 | # 199. Binary Tree Right Side View 2 | 3 | ## Intro 4 | 5 | Given a binary tree, imagine yourself standing on the *right* side of it, return the values of the nodes you can see ordered from top to bottom. 6 | 7 | For example: 8 | 9 | Given the following binary tree, 10 | 11 | ``` 12 | 1 <--- 13 | / \ 14 | 2 3 <--- 15 | \ \ 16 | 5 4 <--- 17 | ``` 18 | 19 | You should return `[1, 3, 4]`. 20 | 21 | ## Thinking 22 | 23 | 思路就是层序遍历,记录每一层的最后一个值。 24 | 25 | ## Solution 26 | 27 | Python 28 | 29 | ```python 30 | # Definition for a binary tree node. 31 | # class TreeNode(object): 32 | # def __init__(self, x): 33 | # self.val = x 34 | # self.left = None 35 | # self.right = None 36 | 37 | class Solution(object): 38 | def rightSideView(self, root): 39 | """ 40 | :type root: TreeNode 41 | :rtype: List[int] 42 | """ 43 | ret = [] 44 | if root: 45 | level = [root] 46 | while level: 47 | ret += level[-1].val, 48 | level = [kid for node in level for kid in (node.left, node.right) if kid] 49 | return ret 50 | ``` -------------------------------------------------------------------------------- /241.md: -------------------------------------------------------------------------------- 1 | # 241. Different Ways to Add Parentheses 2 | 3 | ## Intro 4 | 5 | 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 `*`. 6 | 7 | #### Example 8 | 9 | Input: `"2-1-1"`. 10 | 11 | ``` 12 | ((2-1)-1) = 0 13 | (2-(1-1)) = 2 14 | ``` 15 | 16 | Output: `[0, 2]` 17 | 18 | Input: `"2*3-4*5"` 19 | 20 | ``` 21 | (2*(3-(4*5))) = -34 22 | ((2*3)-(4*5)) = -14 23 | ((2*(3-4))*5) = -10 24 | (2*((3-4)*5)) = -10 25 | (((2*3)-4)*5) = 10 26 | ``` 27 | 28 | Output: `[-34, -14, -10, -10, 10]` 29 | 30 | ## Thinking 31 | 32 | 这题考察了分治思想。分就是将运算符左边和右边分开,那么左右两边可能又可以分,所以可以一直递归下去,而递归的结束就是右边只有树,没有运算符了。而治就是将分开求解的进行结合。 33 | 34 | ## Solution 35 | 36 | Python 37 | 38 | ```python 39 | class Solution(object): 40 | def diffWaysToCompute(self, input): 41 | """ 42 | :type input: str 43 | :rtype: List[int] 44 | """ 45 | return [a+b if c == '+' else a-b if c == '-' else a*b 46 | for i, c in enumerate(input) if c in '+-*' 47 | for a in self.diffWaysToCompute(input[:i]) 48 | for b in self.diffWaysToCompute(input[i+1:])] or [int(input)] 49 | ``` -------------------------------------------------------------------------------- /110.md: -------------------------------------------------------------------------------- 1 | # 110. Balanced Binary Tree 2 | 3 | ## Intro 4 | 5 | Given a binary tree, determine if it is height-balanced. 6 | 7 | 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. 8 | 9 | ## Thinking 10 | 11 | 平衡二叉树具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。 12 | 13 | 所有用递归来比较左右子树,根据上面的性质,可以写出递归条件。 14 | 15 | ## Solution 16 | 17 | Python 18 | 19 | 20 | ```python 21 | # Definition for a binary tree node. 22 | # class TreeNode(object): 23 | # def __init__(self, x): 24 | # self.val = x 25 | # self.left = None 26 | # self.right = None 27 | 28 | class Solution(object): 29 | def depth(self, root): 30 | if root: 31 | return max(self.depth(root.left), self.depth(root.right))+1 32 | else: 33 | return False 34 | 35 | def isBalanced(self, root): 36 | """ 37 | :type root: TreeNode 38 | :rtype: bool 39 | """ 40 | if root: 41 | return abs(self.depth(root.left)-self.depth(root.right)) <= 1 and self.isBalanced(root.left) and self.isBalanced(root.right) 42 | else: 43 | return True 44 | ``` -------------------------------------------------------------------------------- /66.md: -------------------------------------------------------------------------------- 1 | # 66. Plus One 2 | 3 | ## Intro 4 | 5 | Given a non-negative number represented as an array of digits, plus one to the number. 6 | 7 | The digits are stored such that the most significant digit is at the head of the list. 8 | 9 | ## Thinking 10 | 11 | 从用往左进行加1迭代操作,如果大于9,就减10进位。这是比较笨的方法。研究一些例子,可以发现如果各位加1不超过9, 就可以直接返回该数。如果超过,就进行进位操作。这里有个细节,就是用xrange来代替range来减少耗时,因为xrange返回一个生成器而不是list。 12 | 13 | ## Solution 14 | 15 | Python 16 | 17 | ```python 18 | class Solution(object): 19 | def plusOne(self, digits): 20 | """ 21 | :type digits: List[int] 22 | :rtype: List[int] 23 | """ 24 | digits[-1] += 1 25 | for i in xrange(len(digits)-1, 0, -1): 26 | if digits[i] > 9: 27 | digits[i] -= 10 28 | digits[i-1] += 1 29 | if digits[0] > 9: 30 | digits[0] -= 10 31 | return [1] + digits 32 | return digits 33 | ``` 34 | 35 | Another 36 | 37 | ``` 38 | class Solution(object): 39 | def plusOne(self, digits): 40 | for i in xrange(len(digits)-1, -1, -1): 41 | if digits[i] < 9: 42 | digits[i] += 1 43 | return digits 44 | digits[i] = 0 45 | return [1] + digits 46 | ``` -------------------------------------------------------------------------------- /202.md: -------------------------------------------------------------------------------- 1 | # 202. Happy Number 2 | 3 | ## Intro 4 | 5 | Write an algorithm to determine if a number is "happy". 6 | 7 | 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. 8 | 9 | **Example**: 19 is a happy number 10 | 11 | ``` 12 | 1² + 9² = 82 13 | 8² + 2² = 68 14 | 6² + 8² = 100 15 | 1² + 0² + 0² = 1 16 | ``` 17 | 18 | ## Thinking 19 | 20 | 这次只能用笨的方法,还没什么捷径,唯一的方法就是循环计算,将结果加到一个列表里,每次判断计算得到的数是否在列表里。 21 | 22 | ## Solution 23 | 24 | Python 25 | 26 | ```python 27 | class Solution(object): 28 | def isHappy(self, n): 29 | """ 30 | :type n: int 31 | :rtype: bool 32 | """ 33 | nums = [] 34 | while int(n) != 1: 35 | n = str(n) 36 | tmp = 0 37 | for i in range(len(n)): 38 | tmp += int(n[i]) ** 2 39 | if tmp in nums: 40 | return False 41 | nums.append(tmp) 42 | n = tmp 43 | 44 | return True 45 | ``` -------------------------------------------------------------------------------- /342.md: -------------------------------------------------------------------------------- 1 | # 342. Power of Four 2 | 3 | ## Intro 4 | 5 | Given an integer (signed 32 bits), write a function to check whether it is a power of 4. 6 | 7 | #### Example 8 | 9 | Given num = 16, return true. Given num = 5, return false. 10 | 11 | #### Follow up 12 | 13 | Could you solve it without loops/recursion? 14 | 15 | ## Think 16 | 17 | 本来想用位操作的,但是想了想,一时想到好的方法,但分析4的倍数时, 发现了一个规律。将数字转换为二进制,会发现4的倍数中1的后面全为零, 且零的个数是2的倍数。 18 | 19 | 补:参考了一些资料,位操作需要两步。判断是否这个数的二进制只有一个1,和0x55555555相与。 20 | 21 | 22 | ## Solution 23 | 24 | Python 25 | 26 | ```python 27 | class Solution(object): 28 | def isPowerOfFour(self, num): 29 | """ 30 | :type num: int 31 | :rtype: bool 32 | """ 33 | if num <= 0: 34 | return False 35 | else: 36 | return (bin(num)[3:] == len(bin(num)[3:])*'0') and len(bin(num)[3:]) % 2 == 0 37 | ``` 38 | 39 | 另一种方法 40 | 41 | ```python 42 | class Solution(object): 43 | def isPowerOfFour(self, num): 44 | """ 45 | :type num: int 46 | :rtype: bool 47 | """ 48 | if num <= 0: 49 | return False 50 | elif (num & (num-1)) != 0: 51 | return False 52 | return bool(num & 0x55555555) 53 | ``` 54 | -------------------------------------------------------------------------------- /22.md: -------------------------------------------------------------------------------- 1 | # 22. Generate Parentheses 2 | 3 | ## Intro 4 | 5 | Given *n* pairs of parentheses, write a function to generate all combinations of well-formed parentheses. 6 | 7 | For example, given *n* = 3, a solution set is: 8 | 9 | ``` 10 | [ 11 | "((()))", 12 | "(()())", 13 | "(())()", 14 | "()(())", 15 | "()()()" 16 | ] 17 | ``` 18 | 19 | ## Thinking 20 | 21 | 就是求括号的有效组合。一开始我的想法是将左括号代表0,右括号代表1,构建二进制数来寻找规律。发现了个简单的规律,然而并不足以解题。比如n=3, 那么低三位的情况分为有三个1和有两个1,其中有两个1的有效情况是5和3(二进制下)。当n为4,发现低4位有效的情况,也都是奇数。然而后没继续的下去。通过查看资料,大部分的方法都是递归。设置了一对左右值,其实就是左括号个数和右括号个数。若组合有效,那么前缀中左括号的个数肯定要大于右括号个数,因此才存在递归。递归结束的条件是right为0,也就是没有右括号可用了,当然肯定也是没左括号了。 22 | 23 | 假设n=3,可以画出递归树。每个节点分别为前缀,left, right值。 24 | 25 | ![](pic/22.png) 26 | 27 | 28 | 29 | ## Solution 30 | 31 | Python 32 | 33 | ```python 34 | class Solution(object): 35 | def generateParenthesis(self, n): 36 | """ 37 | :type n: int 38 | :rtype: List[str] 39 | """ 40 | ret = [] 41 | def gen(p, left, right): 42 | if left: 43 | gen(p+'(', left-1, right) 44 | if right > left: 45 | gen(p+')', left, right-1) 46 | if not right: 47 | ret.append(p) 48 | return ret 49 | return gen('', n, n) 50 | ``` -------------------------------------------------------------------------------- /141.md: -------------------------------------------------------------------------------- 1 | # 141. Linked List Cycle 2 | 3 | ## Intro 4 | 5 | Given a linked list, determine if it has a cycle in it. 6 | 7 | Follow up: 8 | 9 | Can you solve it without using extra space? 10 | 11 | ## Think 12 | 13 | 这个应该算是一道比较经典的题目,以前就听说过。其中一种解法也非常的巧妙,就是用快慢指针。一个一次走一步,另一个一次走两步,如果有环则两个指针一定会再次相遇,反之则不会。 14 | 15 | ## Solution 16 | 17 | Python 18 | 19 | ```python 20 | # Definition for singly-linked list. 21 | # class ListNode(object): 22 | # def __init__(self, x): 23 | # self.val = x 24 | # self.next = None 25 | 26 | class Solution(object): 27 | def hasCycle(self, head): 28 | """ 29 | :type head: ListNode 30 | :rtype: bool 31 | """ 32 | fast = head 33 | slow = head 34 | while fast and fast.next: 35 | slow = slow.next 36 | fast = fast.next.next 37 | if fast == slow: 38 | return True 39 | return False 40 | ``` 41 | 42 | 另外这个代码速度更快点 43 | 44 | ```python 45 | def hasCycle(self, head): 46 | try: 47 | slow = head 48 | fast = head.next 49 | while slow is not fast: 50 | slow = slow.next 51 | fast = fast.next.next 52 | return True 53 | except: 54 | return False 55 | ``` 56 | -------------------------------------------------------------------------------- /377.md: -------------------------------------------------------------------------------- 1 | # 377. Combination Sum IV 2 | 3 | ## Intro 4 | 5 | Given an integer array with all positive numbers and no duplicates, find the number of possible combinations that add up to a positive integer target. 6 | 7 | #### Example 8 | 9 | ``` 10 | nums = [1, 2, 3] 11 | target = 4 12 | 13 | The possible combination ways are: 14 | (1, 1, 1, 1) 15 | (1, 1, 2) 16 | (1, 2, 1) 17 | (1, 3) 18 | (2, 1, 1) 19 | (2, 2) 20 | (3, 1) 21 | 22 | Note that different sequences are counted as different combinations. 23 | 24 | Therefore the output is 7. 25 | ``` 26 | 27 | ## Thinking 28 | 29 | 这个估计还是DP效果最好。通过事例,可以发现其中的规律。构造一个list dp,首先dp[0] = 1.求目标target返回的结果其实就是求dp[target]的值。以上面example来看,dp[2]其实就等于dp[1]+dp[0],为什么这么说呢,因为组合的和为2,那么产生的可能只可能是dp[1]的组合再加上1,或者组合直接就是(2),这里的前提是nums里有2这个元素。同样,dp[3]就是dp[1]+dp[2]+dp[3]。这是,dp的性质就很明显了。 30 | 31 | ## Solution 32 | 33 | Python 34 | 35 | ```python 36 | class Solution(object): 37 | def combinationSum4(self, nums, target): 38 | """ 39 | :type nums: List[int] 40 | :type target: int 41 | :rtype: int 42 | """ 43 | dp = [1] + [0] * target 44 | for n in xrange(1, target+1): 45 | for i in nums: 46 | if n >= i: 47 | dp[n] += dp[n - i] 48 | return dp[-1] 49 | ``` -------------------------------------------------------------------------------- /223.md: -------------------------------------------------------------------------------- 1 | # 223. Rectangle Area 2 | 3 | ## Intro 4 | 5 | Find the total area covered by two ****rectilinear**** rectangles in a ****2D**** plane. 6 | 7 | Each rectangle is defined by its bottom left corner and top right corner as shown in the figure. 8 | 9 | ![](https://leetcode.com/static/images/problemset/rectangle_area.png) 10 | 11 | 12 | Assume that the total area is never beyond the maximum possible value of ****int****. 13 | 14 | ## Thinking 15 | 16 | 这应该算是一道数学题,根据坐标求覆盖面积。主要解决的就是对于重合的部分的去除。 17 | 如果两个矩形不存在重合的部分,在不需要减去。 18 | 19 | 重合的部分就是判断坐标。当矩形ABCD的右边界在矩形EFGH的左边界左边或者矩形ABCD的左边界在矩形EFGH的右边界的右边,矩形ABCD的下边界在矩形EFGH的上边界上边或者矩形ABCD的上边界在矩形EFGH的下边界下边,那么则不存在重合。 20 | 21 | 按照这个思路,用max和min函数,计算出重叠面积,不存在重叠面积则为0,之后用两个矩阵的面积减去重叠面积,就能得到覆盖面积。 22 | 23 | ## Solution 24 | 25 | Python 26 | 27 | ```python 28 | class Solution(object): 29 | def computeArea(self, A, B, C, D, E, F, G, H): 30 | """ 31 | :type A: int 32 | :type B: int 33 | :type C: int 34 | :type D: int 35 | :type E: int 36 | :type F: int 37 | :type G: int 38 | :type H: int 39 | :rtype: int 40 | """ 41 | area = max(min(C, G) - max(A, E), 0) * max(min(D, H) - max(B, F), 0) 42 | return (C - A) * (D - B) + (G - E) * (H - F) - area 43 | ``` -------------------------------------------------------------------------------- /7.md: -------------------------------------------------------------------------------- 1 | # 7. Reverse Integer 2 | 3 | ## Intro 4 | 5 | Reverse digits of an integer. 6 | 7 | **Example1**: x = 123, return 321 8 | 9 | **Example2**: x = -123, return -321 10 | 11 | ####Note 12 | 13 | Here are some good questions to ask before coding. Bonus points for you if you have already thought through this! 14 | 15 | If the integer's last digit is 0, what should the output be? ie, cases such as 10, 100. 16 | 17 | Did you notice that the reversed integer might overflow? Assume the input is a 32-bit integer, then the reverse of 1000000003 overflows. How should you handle such cases? 18 | 19 | For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows. 20 | 21 | ## Thinking 22 | 23 | 参考题目[190](190.md),仍然可以用字符串来做。但这里存在一个细节问题,越界。因为是整型,所以范围应该在-2147483648~2147483647。因此,在最后的时候要进行判断。 24 | 25 | ## Solution 26 | 27 | Python 28 | 29 | ```python 30 | class Solution(object): 31 | def reverse(self, x): 32 | """ 33 | :type x: int 34 | :rtype: int 35 | """ 36 | x = str(x) 37 | if x[0] == '-': 38 | x = int('-' + (x[1:])[::-1]) 39 | return x if x >= -2147483648 else 0 40 | x = int(x[::-1]) 41 | return x if x <= 2147483647 else 0 42 | ``` 43 | -------------------------------------------------------------------------------- /88.md: -------------------------------------------------------------------------------- 1 | # 88. Merge Sorted Array 2 | 3 | ## Intro 4 | 5 | Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. 6 | 7 | #### Note 8 | 9 | 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. 10 | 11 | ## Thinking 12 | 13 | Python的内置函数太便利了,不能怪我> <。 14 | 15 | 正规点的写法应该是这样,先从后往前进行比较,循环判断num1还是num2. 16 | 17 | ```python 18 | def merge(self, nums1, m, nums2, n): 19 | while m > 0 and n > 0: 20 | if nums1[m-1] >= nums2[n-1]: 21 | nums1[m+n-1] = nums1[m-1] 22 | m -= 1 23 | else: 24 | nums1[m+n-1] = nums2[n-1] 25 | n -= 1 26 | if n > 0: 27 | nums1[:n] = nums2[:n] 28 | ``` 29 | 30 | ## Solution 31 | 32 | Python 33 | 34 | ```python 35 | class Solution(object): 36 | def merge(self, nums1, m, nums2, n): 37 | """ 38 | :type nums1: List[int] 39 | :type m: int 40 | :type nums2: List[int] 41 | :type n: int 42 | :rtype: void Do not return anything, modify nums1 in-place instead. 43 | """ 44 | nums1[:] = sorted(nums1[:m] + nums2[:n]) 45 | ``` 46 | 47 | -------------------------------------------------------------------------------- /1.md: -------------------------------------------------------------------------------- 1 | # 1. Two Sum 2 | 3 | ## Intro 4 | 5 | Given an array of integers, return **indices** of the two numbers such that they add up to a specific target. 6 | 7 | You may assume that each input would have ***exactly*** one solution. 8 | 9 | ####Example 10 | 11 | ``` 12 | Given nums = [2, 7, 11, 15], target = 9, 13 | 14 | Because nums[0] + nums[1] = 2 + 7 = 9, 15 | return [0, 1]. 16 | ``` 17 | 18 | ## Think 19 | 20 | 想到用两层循环,使用列表生成器来优化避免超时。另一种巧妙的方法是用字典, 遍历list,用target减这个数,判断是否还在字典中,不在就添加,在就返回结果。 21 | 22 | ## Solution 23 | 24 | Python 25 | 26 | ```python 27 | class Solution(object): 28 | def twoSum(self, nums, target): 29 | """ 30 | :type nums: List[int] 31 | :type target: int 32 | :rtype: List[int] 33 | """ 34 | l = len(nums) 35 | return [[x, y] for x in xrange(l) for y in xrange(x,l) if nums[x] + nums[y] == target and x != y][0] 36 | ``` 37 | 38 | ```python 39 | class Solution(object): 40 | def twoSum(self, nums, target): 41 | """ 42 | :type nums: List[int] 43 | :type target: int 44 | :rtype: List[int] 45 | """ 46 | d={} 47 | for i,num in enumerate(nums): 48 | if target-num in d: 49 | return d[target-num], i 50 | d[num]=i 51 | ``` -------------------------------------------------------------------------------- /38.md: -------------------------------------------------------------------------------- 1 | # 38. Count and Say 2 | 3 | ## Intro 4 | 5 | The count-and-say sequence is the sequence of integers beginning as follows: 6 | 7 | `1, 11, 21, 1211, 111221, ...` 8 | 9 | `1` is read off as `"one 1"` or `11`. 10 | 11 | `11` is read off as `"two 1s"` or `21`. 12 | 13 | `21` is read off as `"one 2, then one 1"` or `1211`. 14 | 15 | Given an integer n, generate the nth sequence. 16 | 17 | Note: The sequence of integers will be represented as a string. 18 | 19 | ## Think 20 | 21 | 查了一些资料,找到了一个比较容易懂的方法。主要思路就是记录下数字的出现次数。首先记录最左的值,然后从左到右遍历。这是有两种情况,一种是和最左的值相同,那么count加1,如果不同,那么可以知道生成的两个数字一个是count,一个是这个原左值,然后左值left需要变为这个不同的数, count也要变为1。这样循环遍历下去,最终就能得到下一个数。 22 | 23 | 24 | ## Solution 25 | 26 | Python 27 | 28 | ```python 29 | class Solution(object): 30 | def countAndSay(self, n): 31 | """ 32 | :type n: int 33 | :rtype: str 34 | """ 35 | s = '1' 36 | for _ in range(n - 1): 37 | left , t, count = s[0], '', 0 38 | for l in s: 39 | if l == left: 40 | count += 1 41 | else: 42 | t += str(count) + left 43 | left = l 44 | count = 1 45 | t += str(count) + left 46 | s = t 47 | return s 48 | ``` -------------------------------------------------------------------------------- /89.md: -------------------------------------------------------------------------------- 1 | # 89. Gray Code 2 | 3 | ## Intro 4 | 5 | The gray code is a binary numeral system where two successive values differ in only one bit. 6 | 7 | Given a non-negative integer n representing the total number of bits in the code, print the sequence of gray code. A gray code sequence must begin with 0. 8 | 9 | For example, given n = 2, return `[0,1,3,2]`. Its gray code sequence is: 10 | 11 | ``` 12 | 00 - 0 13 | 01 - 1 14 | 11 - 3 15 | 10 - 2 16 | ``` 17 | 18 | #### Note 19 | 20 | For a given n, a gray code sequence is not uniquely defined. 21 | 22 | For example, `[0,2,3,1]` is also a valid gray code sequence according to the above definition. 23 | 24 | For now, the judge is able to judge based on one instance of gray code sequence. Sorry about that. 25 | 26 | ## Thinking 27 | 28 | 先通过举例,对n=2,n=3,n=4的情况进行分析。首先发现list的长度呈指数增长,当n=3,其后一半就是前一半的两倍并倒过来,n=4,后一半并不是前一半的两倍并倒过来,这时就要考虑规律的方向。每个结果的最后一个数都是2的指数,且下一个结果的最后一个数是上一个结果的最后一位的两倍,且数的变化规律与前一半相反。发现规律是新的结果是之前的结果倒过来加上2的(n-1)次方。 29 | 30 | ## Solution 31 | 32 | Python 33 | 34 | ```python 35 | class Solution(object): 36 | def grayCode(self, n): 37 | """ 38 | :type n: int 39 | :rtype: List[int] 40 | """ 41 | ret = [0] 42 | for i in xrange(n): 43 | ret += [2 ** i + x for x in ret[::-1]] 44 | return ret 45 | ``` -------------------------------------------------------------------------------- /347.md: -------------------------------------------------------------------------------- 1 | # 347. Top K Frequent Elements 2 | 3 | ## Intro 4 | 5 | Given a non-empty array of integers, return the **k** most frequent elements. 6 | 7 | For example, 8 | Given `[1,1,1,2,2,3]` and k = 2, return `[1,2]`. 9 | 10 | #### Note 11 | 12 | * You may assume k is always valid, 1 ≤ k ≤ number of unique elements. 13 | 14 | * Your algorithm's time complexity **must be** better than O(n log n), where n is the array's size. 15 | 16 | ## Think 17 | 18 | 这个是用Python collections里的Counter。Counter是计数器,其中有个方法 `most_common([n])` 是获取频率最高的n个元素。 19 | 20 | 当然如果不用这个方法,可以先用排序,然后在选取排序中最高的前k个。 21 | 22 | ## Solution 23 | 24 | Python 25 | 26 | ```python 27 | class Solution(object): 28 | def topKFrequent(self, nums, k): 29 | """ 30 | :type nums: List[int] 31 | :type k: int 32 | :rtype: List[int] 33 | """ 34 | c = collections.Counter(nums) 35 | c = sorted(c.items(),key=lambda x:x[1], reverse=True) 36 | return [x[0] for x in c[:k]] 37 | ``` 38 | 39 | 或者用`most_common()` 40 | 41 | ```python 42 | class Solution(object): 43 | def topKFrequent(self, nums, k): 44 | """ 45 | :type nums: List[int] 46 | :type k: int 47 | :rtype: List[int] 48 | """ 49 | return map(lambda x : x[0], collections.Counter(nums).most_common(k)) 50 | ``` -------------------------------------------------------------------------------- /112.md: -------------------------------------------------------------------------------- 1 | # 112. Path Sum 2 | 3 | ## Intro 4 | 5 | Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum. 6 | 7 | For example: 8 | Given the below binary tree and `sum = 22`, 9 | 10 | ``` 11 | 5 12 | / \ 13 | 4 8 14 | / / \ 15 | 11 13 4 16 | / \ \ 17 | 7 2 1 18 | ``` 19 | 20 | return true, as there exist a root-to-leaf path `5->4->11->2` which sum is 22. 21 | 22 | ## Thinking 23 | 24 | 递归遍历左右子树,直到叶子节点。同时,在遍历的过程中,减去遍历节点的值,最后判断是否sum变为0,变为零则存在。 25 | 26 | ## Solution 27 | 28 | Python 29 | 30 | ```python 31 | # Definition for a binary tree node. 32 | # class TreeNode(object): 33 | # def __init__(self, x): 34 | # self.val = x 35 | # self.left = None 36 | # self.right = None 37 | 38 | class Solution(object): 39 | def hasPathSum(self, root, sum): 40 | """ 41 | :type root: TreeNode 42 | :type sum: int 43 | :rtype: bool 44 | """ 45 | if not root or (not root.left and not root.right): 46 | return bool(root) and (sum == root.val) 47 | sum -= root.val 48 | return self.hasPathSum(root.left, sum) or self.hasPathSum(root.right, sum) 49 | ``` -------------------------------------------------------------------------------- /102.md: -------------------------------------------------------------------------------- 1 | # 102. Binary Tree Level Order Traversal 2 | 3 | ## Intro 4 | 5 | Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to right, level by level). 6 | 7 | For example: 8 | Given binary tree `{3,9,20,#,#,15,7}`, 9 | 10 | ``` 11 | 3 12 | / \ 13 | 9 20 14 | / \ 15 | 15 7 16 | ``` 17 | 18 | return its level order traversal as: 19 | 20 | ``` 21 | [ 22 | [3], 23 | [9,20], 24 | [15,7] 25 | ] 26 | ``` 27 | 28 | ## Thinking 29 | 30 | 层序遍历树,就是[107. Binary Tree Level Order Traversal II](https://github.com/xinqiu/My-LeetCode-Notes/blob/master/107.md)的前面一部分。层序遍历是这样子的,用一个list记录遍历一层的节点,然后对这个队列的里的每个节点的左右儿子继续遍历并记录存在的子树节点,然后继续遍历这个队列直到队列为空。 31 | 32 | ## Solution 33 | 34 | Python 35 | 36 | ```python 37 | # Definition for a binary tree node. 38 | # class TreeNode(object): 39 | # def __init__(self, x): 40 | # self.val = x 41 | # self.left = None 42 | # self.right = None 43 | 44 | class Solution(object): 45 | def levelOrder(self, root): 46 | """ 47 | :type root: TreeNode 48 | :rtype: List[List[int]] 49 | """ 50 | ret = [] 51 | T = [root] 52 | while T and root: 53 | ret.append([x.val for x in T]) 54 | T = [p for n in T for p in (n.left, n.right) if p] 55 | return ret 56 | ``` -------------------------------------------------------------------------------- /19.md: -------------------------------------------------------------------------------- 1 | # 19. Remove Nth Node From End of List 2 | 3 | ## Intro 4 | 5 | Given a linked list, remove the nth node from the end of list and return its head. 6 | 7 | For example, 8 | 9 | ``` 10 | 11 | Given linked list: 1->2->3->4->5, and n = 2. 12 | 13 | After removing the second node from the end, the linked list becomes 1->2->3->5. 14 | ``` 15 | 16 | ####Note 17 | 18 | Given *n* will always be valid. 19 | Try to do this in one pass. 20 | 21 | ## Thinking 22 | 23 | 使用两个指针,一个快指针先先移动 n 次,这时候若快指针的下一个不为空,则快慢两个指针一起移动,当循环停止时,慢指针的next就是倒数第 n 个节点。要注意的是,在快指针先移动的时候,可能会让快指针变为空,所以需要做一个判断。 24 | 25 | ## Solution 26 | 27 | Python 28 | 29 | ```python 30 | # Definition for singly-linked list. 31 | # class ListNode(object): 32 | # def __init__(self, x): 33 | # self.val = x 34 | # self.next = None 35 | 36 | class Solution(object): 37 | def removeNthFromEnd(self, head, n): 38 | """ 39 | :type head: ListNode 40 | :type n: int 41 | :rtype: ListNode 42 | """ 43 | fast = slow = head 44 | for _ in xrange(n): 45 | fast = fast.next 46 | if not fast: 47 | return head.next 48 | while fast.next: 49 | fast = fast.next 50 | slow = slow.next 51 | slow.next = slow.next.next 52 | return head 53 | ``` -------------------------------------------------------------------------------- /20.md: -------------------------------------------------------------------------------- 1 | # 20. Valid Parentheses 2 | 3 | ## Intro 4 | 5 | Given a string containing just the characters `'('`, `')'`, `'{'`, `'}'`, `'['` and `']'`, determine if the input string is valid. 6 | 7 | The brackets must close in the correct order, `"()"` and `"()[]{}"` are all valid but `"(]"` and `"([)]"` are not. 8 | 9 | ## Thinking 10 | 11 | 这题用堆栈比较好做。当元素是"([{"则入堆栈,如果是")}]"则出堆栈。出堆栈时进行比较,判断配对。这里用ascii码来比较是否匹配。 12 | 13 | ## Solution 14 | 15 | Python 16 | 17 | ```python 18 | class Solution(object): 19 | def isValid(self, s): 20 | """ 21 | :type s: str 22 | :rtype: bool 23 | """ 24 | stack = [] 25 | if len(s) % 2 == 1: 26 | return False 27 | for c in s: 28 | if c not in '(){}[]': 29 | return False 30 | if c in '([{': 31 | stack.append(c) 32 | continue 33 | if c in ')}]': 34 | if len(stack) == 0: 35 | return False 36 | t = stack.pop() 37 | if c == ')': 38 | if (ord(c) - 1) != ord(t): 39 | return False 40 | if c in '}]': 41 | if (ord(c) - 2) != ord(t): 42 | return False 43 | return len(stack) == 0 44 | 45 | ``` -------------------------------------------------------------------------------- /216.md: -------------------------------------------------------------------------------- 1 | # 216. Combination Sum III 2 | 3 | ## Intro 4 | 5 | Find all possible combinations of ***k*** numbers that add up to a number ***n***, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers. 6 | 7 | #### Example 1 8 | 9 | Input: ***k*** = 3, ***n*** = 7 10 | 11 | Output: 12 | 13 | ``` 14 | [[1,2,4]] 15 | ``` 16 | 17 | #### Example 2 18 | 19 | Input: ***k*** = 3, ***n*** = 9 20 | 21 | Output: 22 | 23 | ``` 24 | [[1,2,6], [1,3,5], [2,3,4]] 25 | ``` 26 | 27 | ## Thinking 28 | 29 | BFS的思想,记录路径。因为是1到9且每个数字只能出现一次,所以用一个start来记录遍历的最大值,下一次递归时加1,这样就能减少重复的判断。 30 | 递归的结束条件就是k和n都为0,若k为0或者i>n时,没有有效的解,所以需要返回上一层。利用path来记录遍历的路径。 31 | 32 | 33 | ## Solution 34 | 35 | Python 36 | 37 | ```python 38 | class Solution(object): 39 | def combinationSum3(self, k, n): 40 | """ 41 | :type k: int 42 | :type n: int 43 | :rtype: List[List[int]] 44 | """ 45 | ret = [] 46 | self.comb(k, n, 1, [], ret) 47 | return ret 48 | 49 | 50 | def comb(self,k, n, start, path, ret): 51 | if not n and not k: 52 | ret.append(path) 53 | return 54 | for i in xrange(start, 10): 55 | if not k or i > n: 56 | return 57 | self.comb(k-1, n-i, i+1, path+[i], ret) 58 | ``` -------------------------------------------------------------------------------- /36.md: -------------------------------------------------------------------------------- 1 | # 36. Valid Sudoku 2 | 3 | ## Intro 4 | 5 | Determine if a Sudoku is valid, according to: [Sudoku Puzzles - The Rules](http://sudoku.com.au/TheRules.aspx). 6 | 7 | The Sudoku board could be partially filled, where empty cells are filled with the character `'.'`. 8 | 9 | ![](http://upload.wikimedia.org/wikipedia/commons/thumb/f/ff/Sudoku-by-L2G-20050714.svg/250px-Sudoku-by-L2G-20050714.svg.png) 10 | 11 | A partially filled sudoku which is valid. 12 | 13 | #### Note 14 | 15 | A valid Sudoku board (partially filled) is not necessarily solvable. Only the filled cells need to be validated. 16 | 17 | 18 | ## Thinking 19 | 20 | 判断数独是否有效,主要分3个方面: 21 | 22 | * 横行不存在重复 23 | * 纵列不存在重复 24 | * 划分为9个九宫格,每个九宫格里的数不重复 25 | 26 | 这里使用集合,通过判断前后长度来判断是否存在重复。列和行都比较容易,九宫格判断是有技巧的。将九个九宫格分成3 * 3的格子。假设大九宫格行号为i,列号为j,取值范围都为[0, 8],所以用`i/3, j/3`可以轻松的区分开不同小九宫格中的数。比如第4行第7列的数就在[1, 2]这个九宫格中。 27 | 28 | 29 | ## Solution 30 | 31 | Python 32 | 33 | ```python 34 | class Solution(object): 35 | def isValidSudoku(self, board): 36 | """ 37 | :type board: List[List[str]] 38 | :rtype: bool 39 | """ 40 | s = [] 41 | for i, row in enumerate(board): 42 | for j, x in enumerate(row): 43 | if x != '.': 44 | s += (x,j),(i,x),(i/3,j/3,x) 45 | return len(s) == len(set(s)) 46 | ``` -------------------------------------------------------------------------------- /107.md: -------------------------------------------------------------------------------- 1 | # 107. Binary Tree Level Order Traversal II 2 | 3 | ## Intro 4 | 5 | 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). 6 | 7 | For example: 8 | Given binary tree `{3,9,20,#,#,15,7}`, 9 | 10 | ``` 11 | 3 12 | / \ 13 | 9 20 14 | / \ 15 | 15 7 16 | ``` 17 | 18 | return its bottom-up level order traversal as: 19 | 20 | ``` 21 | [ 22 | [15,7], 23 | [9,20], 24 | [3] 25 | ] 26 | ``` 27 | 28 | ## Thinking 29 | 30 | 通过层序遍历,结合堆栈的思想即可。 31 | 32 | 例如上面的例子, 经过层序遍历应该得到`3 9 20 15 7`。层序遍历的方法是用另外一条队列来记录访问的节点,当访问结束,出队列。在访问某节点时,先将该节点的左右儿子节点添加到队列里。这里使用列表生成器来来简化操作,应该算是一个小trick。 33 | 34 | ## Solution 35 | 36 | Python 37 | 38 | ```python 39 | # Definition for a binary tree node. 40 | # class TreeNode(object): 41 | # def __init__(self, x): 42 | # self.val = x 43 | # self.left = None 44 | # self.right = None 45 | 46 | class Solution(object): 47 | def levelOrderBottom(self, root): 48 | """ 49 | :type root: TreeNode 50 | :rtype: List[List[int]] 51 | """ 52 | ret = [] 53 | T = [root] 54 | while T and root: 55 | ret.insert(0,[x.val for x in T]) 56 | T = [p for n in T for p in (n.left, n.right) if p] 57 | return ret 58 | ``` -------------------------------------------------------------------------------- /278.md: -------------------------------------------------------------------------------- 1 | # 278. First Bad Version 2 | 3 | ## Intro 4 | 5 | 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. 6 | 7 | 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. 8 | 9 | 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. 10 | 11 | ## Think 12 | 13 | 二分查找,这个很容易能想到。 14 | 15 | ## Solution 16 | 17 | Python 18 | 19 | ```python 20 | # The isBadVersion API is already defined for you. 21 | # @param version, an integer 22 | # @return a bool 23 | # def isBadVersion(version): 24 | 25 | class Solution(object): 26 | def firstBadVersion(self, n): 27 | """ 28 | :type n: int 29 | :rtype: int 30 | """ 31 | start = 1 32 | end = n 33 | while start < end: 34 | mid = (start + end) / 2 35 | if isBadVersion(mid): 36 | end = mid 37 | else: 38 | start = mid + 1 39 | return start 40 | 41 | ``` -------------------------------------------------------------------------------- /349.md: -------------------------------------------------------------------------------- 1 | # 349. Intersection of Two Arrays 2 | 3 | ## Intro 4 | 5 | Given two arrays, write a function to compute their intersection. 6 | 7 | #### Example 8 | 9 | Given nums1 = `[1, 2, 2, 1]`, nums2 = `[2, 2]`, return `[2]`. 10 | 11 | #### Note 12 | 13 | * Each element in the result must be unique. 14 | * The result can be in any order. 15 | 16 | ## Think 17 | 18 | 第一反应是用集合,然而写出这个一行代码 `return set(nums1) & set(nums2)` 提示 `Line 25: Exception: Type : Not implemented`。没办法,就只能走其他的方法。 19 | 20 | 想到可以用字典。先用生成器生成交集list,再用保存字典的方式,将list转化为dict,最后可以直接用字典内置的keys()函数得到所有的key。 21 | 22 | ``` 23 | class Solution(object): 24 | def intersection(self, nums1, nums2): 25 | """ 26 | :type nums1: List[int] 27 | :type nums2: List[int] 28 | :rtype: List[int] 29 | """ 30 | d = {} 31 | x = [i for i in nums1 if i in nums2] 32 | for i in x: 33 | d[i] = 0 34 | return d.keys() 35 | ``` 36 | 37 | 再Accept之后我又思考了思考,突然想起来之前的set求交集返回的是set类型,需要转化为list,所有之前的代码只要稍加修改就可以通过。 38 | 39 | ## Solution 40 | 41 | Python 42 | 43 | ```python 44 | class Solution(object): 45 | def intersection(self, nums1, nums2): 46 | """ 47 | :type nums1: List[int] 48 | :type nums2: List[int] 49 | :rtype: List[int] 50 | """ 51 | return list(set(nums1) & set(nums2)) 52 | ``` -------------------------------------------------------------------------------- /100.md: -------------------------------------------------------------------------------- 1 | #100. Same Tree 2 | 3 | ## Intro 4 | 5 | Given two binary trees, write a function to check if they are equal or not. 6 | 7 | Two binary trees are considered equal if they are structurally identical and the nodes have the same value. 8 | 9 | ## Thinking 10 | 11 | 如何判断两个树完全相同?其实就是转化为判断两个树的每个节点是否完全相同。类似之前的226,都选择用递归的思路来减少时间复杂度。构造递归主要是确定递归在什么情况需要结束。不难发现,当两个节点都为`None`时,那么肯定这两个节点是相同的,所以返回`True`。 因为`or`只需要满足其一,就能执行分支下的代码,某种程度上说,效率要比`and`要快,所有从`True`的反面`False`来考虑返回条件。满足其一就返回`False`。很明显,如果两个节点的值不同,那么肯定返回`False`,另外如果一个节点不为`None`,另外一个为`None`,则也是`False`。这里要注意一个顺序问题。`or`是从左到右执行判断,如果先比较节点的值,可能会存在某个节点为`None`,并没有`val`这个属性,所以要将值的判断放在`or`的最后。最后就是递归左节点和右节点。 12 | 13 | ## Solution 14 | 15 | 16 | Python 17 | 18 | ```python 19 | 20 | # Definition for a binary tree node. 21 | # class TreeNode(object): 22 | # def __init__(self, x): 23 | # self.val = x 24 | # self.left = None 25 | # self.right = None 26 | 27 | class Solution(object): 28 | def isSameTree(self, p, q): 29 | """ 30 | :type p: TreeNode 31 | :type q: TreeNode 32 | :rtype: bool 33 | """ 34 | if (not p) and (not q): 35 | return True 36 | if (p and not q ) or (not p and q) or p.val != q.val: 37 | return False 38 | return self.isSameTree(p.left,q.left) and self.isSameTree(p.right, q.right) 39 | 40 | ``` -------------------------------------------------------------------------------- /230.md: -------------------------------------------------------------------------------- 1 | # 230. Kth Smallest Element in a BST 2 | 3 | ## Intro 4 | 5 | Given a binary search tree, write a function `kthSmallest` to find the kth smallest element in it. 6 | 7 | #### Note 8 | 9 | You may assume k is always valid, 1 ≤ k ≤ BST's total elements. 10 | 11 | ## Think 12 | 13 | 根据BST的性质,可以知道左子树中所有元素的值均小于根节点的值,右子树中所有元素的值均大于根节点的值。那么只要对树进行中序遍历,就可以得到一个从小到大的访问序列。只需要从树的最左端开始遍历,同时计数,到k个时返回结果即可。 14 | 15 | ## Solution 16 | 17 | Python 18 | 19 | ```python 20 | # Definition for a binary tree node. 21 | # class TreeNode(object): 22 | # def __init__(self, x): 23 | # self.val = x 24 | # self.left = None 25 | # self.right = None 26 | 27 | class Solution(object): 28 | def kthSmallest(self, root, k): 29 | """ 30 | :type root: TreeNode 31 | :type k: int 32 | :rtype: int 33 | """ 34 | if not root: 35 | return [] 36 | 37 | ret = [] 38 | stack = [] 39 | 40 | while root or stack: 41 | while root: 42 | stack.append(root) 43 | root = root.left 44 | if stack: 45 | root = stack.pop() 46 | ret.append(root.val) 47 | k -= 1 48 | if not k: 49 | return root.val 50 | root = root.right 51 | return ret 52 | ``` -------------------------------------------------------------------------------- /96.md: -------------------------------------------------------------------------------- 1 | # 96. Unique Binary Search Trees 2 | 3 | ## Intro 4 | 5 | Given n, how many structurally unique **BST**'s (binary search trees) that store values 1...n? 6 | 7 | For example, 8 | Given n = 3, there are a total of 5 unique BST's. 9 | 10 | ``` 11 | 12 | 1 3 3 2 1 13 | \ / / / \ \ 14 | 3 2 1 1 3 2 15 | / / \ \ 16 | 2 1 2 3 17 | ``` 18 | 19 | ## Thinking 20 | 21 | 这也是dp的思想。对于二叉树,可以将其先看成一个从1到n的数组生成二叉树,问题就变为如何选取root节点。当只有一个节点的时候,只能生成一种二叉树。当长度为2时,能生成2种树。当长度为3时,能生成5种。这5种组合可以看成是当选第一个为root,剩余构成树的组合,选2为root以及选3为root剩余节点构成树的种类之和。剩余节点构成树的种类=左子树种类x右子树种类。 22 | 23 | 所以这时候思路就很清晰了。当全为左子树或者全为右子树时,只有一边的种类。所以假设dp[0]=1,表示没有节点时,默认为1,这是为了方便做乘法。 24 | 25 | 举个例子,假设n=4,dp[0]=dp[1]=1,dp[2]=2。dp[3]=dp[0]xdp[3-0-1]+dp[1]xdp[3-1-1]+dp[2]xdp[3-2-1]=5.dp4=dp[0]xdp[4-0-1]+dp[1]xdp[4-1-1]+dp[2]xdp[4-2-1]+dp[3]xdp[4-3-1]=14. 26 | 27 | ## Solution 28 | 29 | Python 30 | 31 | ```python 32 | class Solution(object): 33 | def numTrees(self, n): 34 | """ 35 | :type n: int 36 | :rtype: int 37 | """ 38 | dp = [0]*(n+1) 39 | dp[0] = dp[1] = 1 40 | if n == 1: 41 | return dp[n] 42 | for i in xrange(2, n+1): 43 | for j in xrange(i): 44 | dp[i] += dp[j] * dp[i-j-1] 45 | return dp[n] 46 | ``` -------------------------------------------------------------------------------- /392.md: -------------------------------------------------------------------------------- 1 | # 392. Is Subsequence 2 | 3 | ## Intro 4 | 5 | Given a string **s** and a string **t**, check if **s** is subsequence of **t**. 6 | 7 | You may assume that there is only lower case English letters in both **s** and **t**. **t** is potentially a very long (length ~= 500,000) string, and **s** is a short string (<=100). 8 | 9 | A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, `"ace"` is a subsequence of `"abcde"` while `"aec"` is not). 10 | 11 | ##### Example 1 12 | 13 | **s** = `"abc"`, **t** = `"ahbgdc"` 14 | 15 | Return `true`. 16 | 17 | ##### Example 2 18 | 19 | **s** = `"axc"`, **t** = `"ahbgdc"` 20 | 21 | Return `false`. 22 | 23 | ## Thinking 24 | 25 | 判断是否是子序列,这里的子序列是不连续的。利用Python字符串处理的find函数,find函数是从第二个参数,也就是start位置开始,向右查找第一个出现的子串。所以可以看成在s里找t的每个元素,看下标是否为递增。就是从左到右,看是否能找到每个t中的元素。 26 | 27 | ## Solution 28 | 29 | Python 30 | 31 | ```python 32 | class Solution(object): 33 | def isSubsequence(self, s, t): 34 | """ 35 | :type s: str 36 | :type t: str 37 | :rtype: bool 38 | """ 39 | index = 0 40 | for c in s: 41 | index = t.find(c, index) 42 | if index < 0: 43 | return False 44 | index += 1 45 | return True 46 | ``` -------------------------------------------------------------------------------- /70.md: -------------------------------------------------------------------------------- 1 | # 70. Climbing Stairs 2 | 3 | ## Intro 4 | 5 | You are climbing a stair case. It takes n steps to reach to the top. 6 | 7 | Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? 8 | 9 | ## Thinking 10 | 11 | 这个应该是最简单的DP——动态规划,虽然没有细细研究过DP,所以就这道题和一些网上的相关资料,分析分析这道题。 12 | 13 | 动态规划的本质,是对问题**状态的定义**和**状态转移方程的定义**。动态规划是通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以递推(或者说分治)的方式去解决。 14 | 15 | #### 状态的定义 16 | 17 | 设Fk为 通过加1或2得到k的组合方法个数。 18 | 19 | 求Fn 得到n的组合方法个数。 20 | 21 | #### 状态转移方程 22 | 23 | 首先,可知起始的条件F0 = 1, F1 = 1。当n为0, 唯一方法就是什么都不增加,所以为1。 24 | 25 | 要求Fn,可以拆分为2个小问题,要么是前一次方法Fx之后再加1就可以得到Fn,要么是前一次方法Fy之后再加2就能得到。那么Fn的方法数就等于Fx + Fy的和。 26 | 27 | 所以Fn = Fn-1 + Fn-2. 28 | 29 | 关于无后效性,就是某阶段的状态一旦确定,则此后过程的演变不再受此前各种状态及决策的影响,简单的说,就是“未来与过去无关”,当前的状态是此前历史的一个完整总结,此前的历史只能通过当前的状态去影响过程未来的演变。这里会发现一旦确定了Fn-1,Fn-2,那么就确定了Fn。因为Fn的得到只能是最后一次增加不是增加1就是增加2。 30 | 31 | 最后会发现这个就是一个Fibonacci数列,当然也可以用数学公式直接求解第n个Fibonacci数,然而好像sqrt函数要更耗时些。 32 | 33 | ## Solution 34 | 35 | Python 36 | 37 | ```python 38 | class Solution(object): 39 | def climbStairs(self, n): 40 | """ 41 | :type n: int 42 | :rtype: int 43 | """ 44 | f = [] 45 | f.extend([1, 1]) 46 | if n <= 1: 47 | return f[n] 48 | else: 49 | for i in range(2, n + 1): 50 | f.append(f[i - 1] + f[i - 2]) 51 | return f[n] 52 | ``` 53 | 54 | -------------------------------------------------------------------------------- /Leetcode/225.py: -------------------------------------------------------------------------------- 1 | from Queue import Queue 2 | 3 | class MyStack(object): 4 | 5 | def __init__(self): 6 | """ 7 | Initialize your data structure here. 8 | """ 9 | self.stack = Queue() 10 | self.count = 0 11 | 12 | def push(self, x): 13 | """ 14 | Push element x onto stack. 15 | :type x: int 16 | :rtype: None 17 | """ 18 | self.stack.put(x) 19 | self.count += 1 20 | self.top_element = x 21 | 22 | def pop(self): 23 | """ 24 | Removes the element on top of the stack and returns that element. 25 | :rtype: int 26 | """ 27 | t = Queue() 28 | for i in range(self.count-1): 29 | self.top_element = self.stack.get() 30 | t.put(self.top_element) 31 | ret = self.stack.get() 32 | self.count -= 1 33 | self.stack = t 34 | return ret 35 | 36 | def top(self): 37 | """ 38 | Get the top element. 39 | :rtype: int 40 | """ 41 | return self.top_element 42 | 43 | def empty(self): 44 | """ 45 | Returns whether the stack is empty. 46 | :rtype: bool 47 | """ 48 | return self.stack.empty() 49 | 50 | # Your MyStack object will be instantiated and called as such: 51 | # obj = MyStack() 52 | # obj.push(x) 53 | # param_2 = obj.pop() 54 | # param_3 = obj.top() 55 | # param_4 = obj.empty() -------------------------------------------------------------------------------- /12.md: -------------------------------------------------------------------------------- 1 | # 12. Integer to Roman 2 | 3 | ## Intro 4 | 5 | Given an integer, convert it to a roman numeral. 6 | 7 | Input is guaranteed to be within the range from 1 to 3999. 8 | 9 | ## Think 10 | 11 | 这道题是将[13.md]翻过了,数字到罗马数字的转换。罗马数字的规律是用I,V,X,L,C,D,M字符组成。 12 | 13 | 1. 相同的数字连写、所表示的数等于这些数字相加得到的数、如:Ⅲ=3; 14 | 2. 小的数字在大的数字的右边、所表示的数等于这些数字相加得到的数、 如:Ⅷ=8、Ⅻ=12; 15 | 3. 小的数字、(限于 Ⅰ、X 和 C)在大的数字的左边、所表示的数等于大数减小数得到的数、如:Ⅳ=4、Ⅸ=9; 16 | 4. 正常使用时、连写的数字重复不得超过三次; 17 | 18 | 所以比较简单的方法就是用多个条件判断,通过求余来从右到左,确定每一位的数字,进行比较。 19 | 20 | ## Solution 21 | 22 | Python 23 | 24 | ```python 25 | class Solution(object): 26 | def intToRoman(self, num): 27 | """ 28 | :type num: int 29 | :rtype: str 30 | """ 31 | roman = {1:'I', 5:'V', 10:'X', 50:'L', 100:'C', 500:'D', 1000:'M'} 32 | ret = '' 33 | index = 1 34 | while num: 35 | mod = num % 10 36 | if mod >= 1 and mod < 4: 37 | ret = mod * roman[index] + ret 38 | elif mod == 4: 39 | ret = roman[index] + roman[5*index] + ret 40 | elif mod == 5: 41 | ret = roman[5*index] + ret 42 | elif mod > 5 and mod < 9: 43 | ret = roman[5*index] + (mod - 5) * roman[index] + ret 44 | elif mod == 9: 45 | ret = roman[index] + roman[10*index] + ret 46 | index *= 10 47 | num /= 10 48 | return ret 49 | ``` -------------------------------------------------------------------------------- /167.md: -------------------------------------------------------------------------------- 1 | # 167. Two Sum II - Input array is sorted 2 | 3 | ## Intro 4 | 5 | Given an array of integers that is already ***sorted in ascending order***, find two numbers such that they add up to a specific target number. 6 | 7 | The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based. 8 | 9 | You may assume that each input would have exactly one solution. 10 | 11 | **Input**: numbers={2, 7, 11, 15}, target=9 12 | 13 | **Output**: index1=1, index2=2 14 | 15 | ## Thinking 16 | 17 | 一开始我考虑的是二分法,但在设计二分法的时候,突然想到从左右两端向中间移动,也能找到结果。相当于用两个变量记录首尾的下标,如果两个数相加小于target,左边就向右移一位,如果大于,右边就向左一位。因为本题保证有唯一解,所以不用担心死循环。 18 | 19 | ## Solution 20 | 21 | Python 22 | 23 | ```python 24 | class Solution(object): 25 | def twoSum(self, numbers, target): 26 | """ 27 | :type numbers: List[int] 28 | :type target: int 29 | :rtype: List[int] 30 | """ 31 | n = len(numbers) 32 | start = 0 33 | end = n 34 | if target == numbers[0]+numbers[-1]: 35 | return 1, n 36 | while numbers[start]+ numbers[end-1] != target: 37 | if numbers[start]+ numbers[end-1] < target: 38 | start += 1 39 | elif numbers[start]+ numbers[end-1] > target: 40 | end -= 1 41 | return [start+1, end] 42 | ``` -------------------------------------------------------------------------------- /374.md: -------------------------------------------------------------------------------- 1 | # 374. Guess Number Higher or Lower 2 | 3 | ## Intro 4 | 5 | We are playing the Guess Game. The game is as follows: 6 | 7 | I pick a number from 1 to n. You have to guess which number I picked. 8 | 9 | Every time you guess wrong, I'll tell you whether the number is higher or lower. 10 | 11 | You call a pre-defined API `guess(int num)` which returns 3 possible results (-1, 1, or 0): 12 | 13 | ``` 14 | -1 : My number is lower 15 | 1 : My number is higher 16 | 0 : Congrats! You got it! 17 | ``` 18 | 19 | #### Example 20 | 21 | ``` 22 | n = 10, I pick 6. 23 | 24 | Return 6. 25 | ``` 26 | 27 | ## Thinking 28 | 29 | 其实就是二分查找,找出要猜的数。管家这里有个陷阱,就是他的guess API。My number 其实说的是它的数, 而不是我们输入的数。也就是说,如果我输入的数比它大,它返回-1. 30 | 31 | ## Solution 32 | 33 | 34 | Python 35 | 36 | ```python 37 | # The guess API is already defined for you. 38 | # @param num, your guess 39 | # @return -1 if my number is lower, 1 if my number is higher, otherwise return 0 40 | # def guess(num): 41 | 42 | class Solution(object): 43 | def guessNumber(self, n): 44 | """ 45 | :type n: int 46 | :rtype: int 47 | """ 48 | start = 1 49 | end = n 50 | while start <= end: 51 | mid = (start + end) / 2 52 | g = guess(mid) 53 | if g == 0: 54 | return mid 55 | elif g < 0: 56 | end = mid - 1 57 | else: 58 | start = mid + 1 59 | ``` -------------------------------------------------------------------------------- /Leetcode/107.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | class TreeNode(object): 3 | def __init__(self, x): 4 | self.val = x 5 | self.left = None 6 | self.right = None 7 | 8 | class Solution(object): 9 | def levelOrderBottom(self, root): 10 | """ 11 | :type root: TreeNode 12 | :rtype: List[List[int]] 13 | """ 14 | if not root: 15 | return [] 16 | 17 | ret = [] 18 | queue = [root] 19 | 20 | while queue: 21 | level_size = len(queue) 22 | current_level = [] 23 | for _ in range(level_size): 24 | node = queue.pop(0) 25 | current_level.append(node.val) 26 | if node.left: 27 | queue.append(node.left) 28 | if node.right: 29 | queue.append(node.right) 30 | ret.append(current_level) 31 | 32 | return ret 33 | 34 | 35 | """ 36 | class Solution(object): 37 | def levelOrderBottom(self, root): 38 | ret = [] 39 | T = [root] 40 | while T and root: 41 | ret.insert(0,[x.val for x in T]) 42 | T = [p for n in T for p in (n.left, n.right) if p] 43 | return ret 44 | """ 45 | 46 | solution = Solution() 47 | 48 | A = TreeNode(1) 49 | B = TreeNode(3) 50 | C = TreeNode(2) 51 | D = TreeNode(4) 52 | 53 | A.left = B 54 | A.right = C 55 | C.left = D 56 | 57 | print solution.levelOrderBottom(A) -------------------------------------------------------------------------------- /35.md: -------------------------------------------------------------------------------- 1 | # 35. Search Insert Position 2 | 3 | ## Intro 4 | 5 | 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. 6 | 7 | You may assume no duplicates in the array. 8 | 9 | Here are few examples. 10 | 11 | `[1,3,5,6]`, 5 → 2 12 | 13 | `[1,3,5,6]`, 2 → 1 14 | 15 | `[1,3,5,6]`, 7 → 4 16 | 17 | `[1,3,5,6]`, 0 → 0 18 | 19 | ## Thinking 20 | 21 | 先判断是否target大于数组最大的值,然后循环遍历出第一个大于等于target的索引。 22 | 当然,在搜索的时候,可以使用二分查找,这样时间复杂度更低。 23 | 24 | ## Solution 25 | 26 | Python 27 | 28 | ```python 29 | class Solution(object): 30 | def searchInsert(self, nums, target): 31 | """ 32 | :type nums: List[int] 33 | :type target: int 34 | :rtype: int 35 | """ 36 | if target > nums[-1]: 37 | return len(nums) 38 | for i in xrange(len(nums)): 39 | if nums[i] >= target: 40 | return i 41 | ``` 42 | 43 | ```python 44 | class Solution(object): 45 | def searchInsert(self, nums, target): 46 | """ 47 | :type nums: List[int] 48 | :type target: int 49 | :rtype: int 50 | """ 51 | start = 0 52 | end = len(nums) 53 | while start < end: 54 | mid = (start + end) / 2 55 | if nums[mid] >= target: 56 | end = mid 57 | else: 58 | start = mid + 1 59 | return start 60 | ``` -------------------------------------------------------------------------------- /309.md: -------------------------------------------------------------------------------- 1 | # 309. Best Time to Buy and Sell Stock with Cooldown 2 | 3 | ## Intro 4 | 5 | Say you have an array for which the ith element is the price of a given stock on day i. 6 | 7 | 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) with the following restrictions: 8 | 9 | * You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again). 10 | * After you sell your stock, you cannot buy stock on next day. (ie, cooldown 1 day) 11 | 12 | #### Example 13 | 14 | ``` 15 | prices = [1, 2, 3, 0, 2] 16 | maxProfit = 3 17 | transactions = [buy, sell, cooldown, buy, sell] 18 | ``` 19 | 20 | ## Thinking 21 | 22 | 思考了一段时间,感觉是dp,但是没想到这个是多个状态的转移。 23 | 24 | ![](pic/309.png) 25 | 26 | Free代表没买,Buy代表买入股票以后,Sell代表卖出以后。这三种状态得转移如图所示。Free的产生是由上一次的Free的状态和Sell的状态比较大小得来,Buy是由上一次Buy和Free减当前股票价格比大小得来,Sell是由上一次Buy加上当前股票价格得来。最后的利润结果其实就是比较最后时Free和Sell的大小。 27 | 28 | 29 | ## Solution 30 | 31 | Python 32 | 33 | ```python 34 | class Solution(object): 35 | def maxProfit(self, prices): 36 | """ 37 | :type prices: List[int] 38 | :rtype: int 39 | """ 40 | if not prices: 41 | return 0 42 | free = 0 43 | buy = 0 - prices[0] 44 | sell = float('-inf') 45 | for p in prices: 46 | free, buy, sell = max(free, sell), max(buy, free - p), buy + p 47 | return max(free, sell) 48 | ``` -------------------------------------------------------------------------------- /62.md: -------------------------------------------------------------------------------- 1 | # 62. Unique Paths 2 | 3 | ## Intro 4 | 5 | A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). 6 | 7 | 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). 8 | 9 | How many possible unique paths are there? 10 | 11 | ![](http://leetcode.com/wp-content/uploads/2014/12/robot_maze.png) 12 | 13 | Above is a 3 x 7 grid. How many possible unique paths are there? 14 | 15 | **Note**: m and n will be at most 100. 16 | 17 | 18 | ## Thinking 19 | 20 | 就是高中的组合排列问题,如果是m * n的格子,那就一共走了m+n-2步,就是求总步数中,(m-1)或者(n-1)的组合。就是求公式C(m+n-2, m-1)。这里用到math包里的阶乘函数。 21 | 22 | 另外还有一种使用DP的思想。观察图,可以知道终点只能由它的上边或者它的左边得到,所以就进而转化为到达终点左边的点的路数加上到达终点上边的点的路数就是结果。 23 | 24 | ## Solution 25 | 26 | Python 27 | 28 | ```python 29 | class Solution(object): 30 | def uniquePaths(self, m, n): 31 | """ 32 | :type m: int 33 | :type n: int 34 | :rtype: int 35 | """ 36 | return math.factorial(m + n - 2) / (math.factorial(m - 1) * math.factorial(n - 1)) 37 | ``` 38 | 39 | DP 40 | ``` 41 | class Solution(object): 42 | def uniquePaths(self, m, n): 43 | """ 44 | :type m: int 45 | :type n: int 46 | :rtype: int 47 | """ 48 | dp = [[1]*n] * m 49 | for i in xrange(1, m): 50 | for j in xrange(1, n): 51 | dp[i][j] = dp[i-1][j]+dp[i][j-1] 52 | return dp[m-1][n-1] 53 | ``` -------------------------------------------------------------------------------- /303.md: -------------------------------------------------------------------------------- 1 | # 303. Range Sum Query - Immutable 2 | 3 | 4 | ## Intro 5 | 6 | Given an integer array nums, find the sum of the elements between indices *i* and *j* (*i* ≤ *j*), inclusive. 7 | 8 | #### Example 9 | 10 | ``` 11 | Given nums = [-2, 0, 3, -5, 2, -1] 12 | 13 | sumRange(0, 2) -> 1 14 | sumRange(2, 5) -> -1 15 | sumRange(0, 5) -> -3 16 | ``` 17 | 18 | #### Note 19 | 20 | 1. You may assume that the array does not change. 21 | 2. There are many calls to *sumRange* function. 22 | 23 | ## Think 24 | 25 | 考虑到提示中sumRange函数经常被调用,所以不能在sumRange里每次进行循环求和,那么其他的办法就是计算出一个sum表。用sum表来记录从第一个数到第N个数的和是多少,那么通过相减,就能得到两个索引直接的元素和。这里有个细节是可能nums没有元素或者只有一个元素。 26 | 27 | ## Solution 28 | 29 | Python 30 | 31 | ```python 32 | class NumArray(object): 33 | def __init__(self, nums): 34 | """ 35 | initialize your data structure here. 36 | :type nums: List[int] 37 | """ 38 | self.nums = nums 39 | self.sumList = [] 40 | sum = 0 41 | for i in xrange(len(nums)): 42 | sum += nums[i] 43 | self.sumList.append(sum) 44 | 45 | def sumRange(self, i, j): 46 | """ 47 | sum of elements nums[i..j], inclusive. 48 | :type i: int 49 | :type j: int 50 | :rtype: int 51 | """ 52 | return self.sumList[j] - self.sumList[i] + self.nums[i] 53 | 54 | 55 | # Your NumArray object will be instantiated and called as such: 56 | # numArray = NumArray(nums) 57 | # numArray.sumRange(0, 1) 58 | # numArray.sumRange(1, 2) 59 | ``` -------------------------------------------------------------------------------- /231.md: -------------------------------------------------------------------------------- 1 | # 231. Power of Two 2 | 3 | ## Intro 4 | 5 | Given an integer, write a function to determine if it is a power of two. 6 | 7 | ## Thinking 8 | 9 | 这道题有多种方法,首先介绍O(n)的思路。如果一个数是2的幂,那么一直除以2会等于1.这里循环除以2的条件是这个数要能被2整除。要注意的是0这一特殊条件。 10 | 11 | 另外一种方法类似[326](https://github.com/xinqiu/My-LeetCode-Notes/blob/master/326.md)的思路,让int范围下的最大的2的幂2147483648来除以这个数。 12 | 13 | 还有一种巧妙的方法,使用原码正负之间的区别。参考CSAPP P122上的介绍,求一个数的相反数的原码,是将这个数二进制原码最右边的一个1位不变,其左边全部取反。假设这个数是3——[0011],所以-3——[1101]。假设这个数是4——[0100],所以-4——[1100]。因为只要是2的幂,那么这个数的二进制中只有1个1,其相反数原码的变化是将1位左边的0全变成1,那么正负原码相与应该还等于正数。 14 | 15 | ## Solution 16 | 17 | Python 18 | 19 | O(n) 20 | 21 | ```python 22 | class Solution(object): 23 | def isPowerOfTwo(self, n): 24 | """ 25 | :type n: int 26 | :rtype: bool 27 | """ 28 | if n == 0: 29 | return False 30 | while n % 2 == 0: 31 | n >>= 1 32 | if n == 1: 33 | return True 34 | else: 35 | return False 36 | ``` 37 | 38 | O(1) 39 | 40 | ```python 41 | class Solution(object): 42 | def isPowerOfTwo(self, n): 43 | """ 44 | :type n: int 45 | :rtype: bool 46 | """ 47 | return n > 0 and 2147483648 % n == 0 48 | ``` 49 | 50 | O(1) 51 | 52 | ```python 53 | class Solution(object): 54 | def isPowerOfTwo(self, n): 55 | """ 56 | :type n: int 57 | :rtype: bool 58 | """ 59 | if n <= 0: 60 | return False 61 | else: 62 | return n == (-n & n) 63 | ``` -------------------------------------------------------------------------------- /319.md: -------------------------------------------------------------------------------- 1 | # 319. Bulb Switcher 2 | 3 | ## Intro 4 | 5 | There are n bulbs that are initially off. You first turn on all the bulbs. Then, you turn off every second bulb. On the third round, you toggle every third bulb (turning on if it's off or turning off if it's on). For the ith round, you toggle every i bulb. For the nth round, you only toggle the last bulb. Find how many bulbs are on after n rounds. 6 | 7 | #### Example 8 | 9 | Given n = 3. 10 | 11 | At first, the three bulbs are **[off, off, off]**. 12 | 13 | After first round, the three bulbs are **[on, on, on]**. 14 | 15 | After second round, the three bulbs are **[on, off, on]**. 16 | 17 | After third round, the three bulbs are **[on, off, off]**. 18 | 19 | So you should return 1, because there is only one bulb is on. 20 | 21 | ## Think 22 | 23 | 如果用暴力的方法,肯定会超时,那么这里面肯定存在某种规律。为了方便,可以规定0为off,1为on。假设n = 8,那么初始状态就是0000 0000. 24 | 25 | 第一次 1111 1111 26 | 27 | 第二次 1010 1010 28 | 29 | 第三次 1000 1110 30 | 31 | 第四次 1001 1111 32 | 33 | 第五次 1001 0111 34 | 35 | 第六次 1001 0011 36 | 37 | 第七次 1001 0001 38 | 39 | 第八次 1001 0000 40 | 41 | 所以结果返回2. 42 | 43 | 对于素数,那么肯定是1和它本身会进行改变状态。 44 | 45 | 对于非素数,其中偶数肯定是会进行偶数次改变状态。对于奇数,大部分也是翻偶数次。 46 | 47 | 只有一种情况,平方数,它必定是进行了奇数次改变状态。 48 | 49 | 那么对于平方数进行判断,会发现返回结果就是根号n。 50 | 51 | 进而可以得出一般的结论,返回值就是根号下的输入值。 52 | 53 | ## Solution 54 | 55 | Python 56 | 57 | ```python 58 | class Solution(object): 59 | def bulbSwitch(self, n): 60 | """ 61 | :type n: int 62 | :rtype: int 63 | """ 64 | from math import sqrt 65 | return int(sqrt(n)) 66 | ``` -------------------------------------------------------------------------------- /290.md: -------------------------------------------------------------------------------- 1 | # 290. Word Pattern 2 | 3 | ## Intro 4 | 5 | Given a `pattern` and a string `str`, find if `str` follows the same pattern. 6 | 7 | Here **follow** means a full match, such that there is a bijection between a letter in `pattern` and a **non-empty** word in `str`. 8 | 9 | ####Examples 10 | 11 | pattern = `"abba"`, str = `"dog cat cat dog"` should return true. 12 | pattern = `"abba"`, str = `"dog cat cat fish"` should return false. 13 | pattern = `"aaaa"`, str = `"dog cat cat dog"` should return false. 14 | pattern = `"abba"`, str = `"dog dog dog dog"` should return false. 15 | 16 | ####Notes 17 | 18 | You may assume `pattern` contains only lowercase letters, and `str` contains lowercase letters separated by a single space. 19 | 20 | ## Think 21 | 22 | 有点类似 [205](205.md), 可以使用zip和set。也可以使用另一种方法,用index和find。字符串用find,列表用index,如果用map分别对pattern和str进行操作,如果相同则匹配。 23 | 24 | ## Solution 25 | 26 | Python 27 | 28 | ```python 29 | class Solution(object): 30 | def wordPattern(self, pattern, str): 31 | """ 32 | :type pattern: str 33 | :type str: str 34 | :rtype: bool 35 | """ 36 | return len(set(zip(pattern, str.split()))) == len(set(pattern)) == len(set(str.split())) and len(pattern) == len(str.split()) 37 | ``` 38 | 39 | Another 40 | 41 | ```python 42 | class Solution(object): 43 | def wordPattern(self, pattern, str): 44 | """ 45 | :type pattern: str 46 | :type str: str 47 | :rtype: bool 48 | """ 49 | s = str.split() 50 | return map(pattern.find, pattern) == map(s.index, s) 51 | ``` -------------------------------------------------------------------------------- /Leetcode/155.py: -------------------------------------------------------------------------------- 1 | class MinStack(object): 2 | 3 | def __init__(self): 4 | """ 5 | initialize your data structure here. 6 | """ 7 | self.stack = [] 8 | 9 | def push(self, x): 10 | """ 11 | :type x: int 12 | :rtype: None 13 | """ 14 | self.stack.append(x) 15 | 16 | def pop(self): 17 | """ 18 | :rtype: None 19 | """ 20 | t = self.stack[-1] 21 | self.stack = self.stack[:-1] 22 | return t 23 | 24 | def top(self): 25 | """ 26 | :rtype: int 27 | """ 28 | return self.stack[-1] 29 | 30 | def getMin(self): 31 | """ 32 | :rtype: int 33 | """ 34 | return min(self.stack) 35 | 36 | # class MinStack: 37 | # 38 | # def __init__(self): 39 | # """ 40 | # initialize your data structure here. 41 | # """ 42 | # self.data = [] 43 | # self.min = None 44 | # 45 | # def push(self, x): 46 | # if self.min == None or x <= self.min: 47 | # self.data.append(self.min) 48 | # self.min = x 49 | # self.data.append(x) 50 | # 51 | # def pop(self): 52 | # if self.data.pop() == self.min: 53 | # self.min = self.data.pop() 54 | # 55 | # def top(self): 56 | # return self.data[-1] 57 | # 58 | # def getMin(self): 59 | # return self.min 60 | 61 | # Your MinStack object will be instantiated and called as such: 62 | # obj = MinStack() 63 | # obj.push(x) 64 | # obj.pop() 65 | # param_3 = obj.top() 66 | # param_4 = obj.getMin() -------------------------------------------------------------------------------- /Leetcode/232.py: -------------------------------------------------------------------------------- 1 | class MyQueue(object): 2 | 3 | def __init__(self): 4 | """ 5 | Initialize your data structure here. 6 | """ 7 | self.queue = [] 8 | self.count = 0 9 | self.front = None 10 | 11 | def push(self, x): 12 | """ 13 | Push element x to the back of queue. 14 | :type x: int 15 | :rtype: None 16 | """ 17 | self.count += 1 18 | self.queue.append(x) 19 | if self.count == 1: 20 | self.front = x 21 | 22 | 23 | 24 | def pop(self): 25 | """ 26 | Removes the element from in front of queue and returns that element. 27 | :rtype: int 28 | """ 29 | t = [] 30 | 31 | for _ in range(self.count): 32 | t.append(self.queue.pop()) 33 | ret = t.pop() 34 | if len(t) != 0: 35 | self.front = t[-1] 36 | else: 37 | self.front = None 38 | 39 | self.count -= 1 40 | for _ in range(self.count): 41 | self.queue.append(t.pop()) 42 | return ret 43 | 44 | 45 | def peek(self): 46 | """ 47 | Get the front element. 48 | :rtype: int 49 | """ 50 | return self.front 51 | 52 | def empty(self): 53 | """ 54 | Returns whether the queue is empty. 55 | :rtype: bool 56 | """ 57 | return self.count == 0 58 | 59 | # Your MyQueue object will be instantiated and called as such: 60 | # obj = MyQueue() 61 | # obj.push(x) 62 | # param_2 = obj.pop() 63 | # param_3 = obj.peek() 64 | # param_4 = obj.empty() -------------------------------------------------------------------------------- /242.md: -------------------------------------------------------------------------------- 1 | #242. Valid Anagram 2 | 3 | ## Intro 4 | 5 | Given two strings s and t, write a function to determine if t is an anagram of s. 6 | 7 | For example, 8 | s = "anagram", t = "nagaram", return true. 9 | s = "rat", t = "car", return false. 10 | 11 | ###Note 12 | You may assume the string contains only lowercase alphabets. 13 | 14 | ###Follow up 15 | What if the inputs contain unicode characters? How would you adapt your solution to such case? 16 | 17 | ## Thinking 18 | 19 | 开始想到的一个方法不出意外就TLE: 20 | 21 | ```python 22 | class Solution(object): 23 | def isAnagram(self, s, t): 24 | """ 25 | :type nums: List[int] 26 | :rtype: List[int] 27 | """ 28 | if len(s) == len(t): 29 | for c in s: 30 | if s.count(c) != t.count(c): 31 | return False 32 | return True 33 | return False 34 | 35 | ``` 36 | 37 | 思路很简单,如果两个字符串长度不一样,肯定返回`False`.如果长度一样,就开始比较字符串的相同元素的个数是否一样。上面的代码会TLE的原因就在`for c in s`这一行。如果直接这样,`count`执行次数为`len(s)`,毕竟`count`也很耗时,所以就很容易TLE。一个优化的方法就是使用`set`函数。`set`是一个无序不重复元素集,这样处理字符串后,`count`执行次数缩小为小于等于26。这一优化减少了很多不必要的时间开支。当然也有另一种办法就是建立dict来统计每个字母的个数,最后比较两个dict是否相同。 38 | 39 | ## Solution 40 | 41 | Python 42 | 43 | ```python 44 | class Solution(object): 45 | def isAnagram(self, s, t): 46 | """ 47 | :type s: str 48 | :type t: str 49 | :rtype: bool 50 | """ 51 | if len(s) == len(t): 52 | for c in set(s): 53 | if s.count(c) != t.count(c): 54 | return False 55 | return True 56 | return False 57 | ``` -------------------------------------------------------------------------------- /198.md: -------------------------------------------------------------------------------- 1 | # 198. House Robber 2 | 3 | ## Intro 4 | 5 | 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.** 6 | 7 | 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.** 8 | 9 | ## Thinking 10 | 11 | 很明显这道题会用到DP的思想。回忆[70.Climbing Stairs](https://github.com/xinqiu/My-LeetCode-Notes/blob/master/70.md),关键是要分析出状态转移方程。对于第n个房子,有两种状态——偷和不偷。用money来记录最大值。如果选择偷,那么上一个房子必然不能偷,所以money[n]就是money[n-2]+nums[i]。如果不偷,上一个房间的选择就无所谓,money[n]其实就是money[n-1]。在对第n个房子进行决策时,money应该是money[n-2]+num[n]与money[n-1]的最大值。通过迭代,来进行DP。另外, 开始条件也可以确定出来。如果n为0, 则返回0, 如果n为1, 则返回nums[0],如果n大于等于2, 就需要进行比较。 12 | 13 | ## Solution 14 | 15 | Python 16 | 17 | ```python 18 | class Solution(object): 19 | def rob(self, nums): 20 | """ 21 | :type nums: List[int] 22 | :rtype: int 23 | """ 24 | if len(nums) == 0: 25 | return 0 26 | money = [] 27 | for i in range(len(nums)): 28 | if i == 0: 29 | money.append(nums[0]) 30 | continue 31 | if i == 1: 32 | money.append(max(nums[0], nums[1])) 33 | continue 34 | else: 35 | money.append(max(money[i-2]+nums[i],money[i-1])) 36 | return max(money[len(nums)-1], money[len(nums)-2]) 37 | ``` -------------------------------------------------------------------------------- /59.md: -------------------------------------------------------------------------------- 1 | # 59. Spiral Matrix II 2 | 3 | ## Intro 4 | 5 | Given an integer n, generate a square matrix filled with elements from 1 to n^2 in spiral order. 6 | 7 | For example, 8 | Given n = `3`, 9 | 10 | You should return the following matrix: 11 | 12 | ``` 13 | [ 14 | [ 1, 2, 3 ], 15 | [ 8, 9, 4 ], 16 | [ 7, 6, 5 ] 17 | ] 18 | ``` 19 | 20 | ## Thinking 21 | 22 | 参考[54. Spiral Matrix](54.md)的方式,只需要改一下就可以了。将遍历改为修改值。 23 | 24 | ## Solution 25 | 26 | Python 27 | 28 | ```python 29 | class Solution(object): 30 | def generateMatrix(self, n): 31 | """ 32 | :type n: int 33 | :rtype: List[List[int]] 34 | """ 35 | matrix = [[0] * n for _ in xrange(n)] 36 | index = 1 37 | x = y = n 38 | i = j = -1 39 | while x > 1 and y > 1: 40 | i += 1 41 | j += 1 42 | for k in xrange(y - 1): 43 | matrix[i][j] = index 44 | index += 1 45 | j += 1 46 | for k in xrange(x - 1): 47 | matrix[i][j] = index 48 | index += 1 49 | i += 1 50 | for k in xrange(y - 1): 51 | matrix[i][j] = index 52 | index += 1 53 | j -= 1 54 | for k in xrange(x - 1): 55 | matrix[i][j] = index 56 | index += 1 57 | i -= 1 58 | x -= 2 59 | y -= 2 60 | i += 1 61 | j += 1 62 | 63 | for k in xrange(y): 64 | matrix[i][j]= index 65 | index += 1 66 | j += 1 67 | 68 | return matrix 69 | ``` -------------------------------------------------------------------------------- /Leetcode/110.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | ''' 9 | class Solution: 10 | def isBalanced(self, root: TreeNode) -> bool: 11 | return self.depth(root) != -1 12 | 13 | def depth(self, root): 14 | if not root: return 0 15 | left = self.depth(root.left) 16 | if left == -1: return -1 17 | right = self.depth(root.right) 18 | if right == -1: return -1 19 | return max(left, right) + 1 if abs(left - right) < 2 else -1 20 | ''' 21 | 22 | ''' 23 | class Solution: 24 | def isBalanced(self, root: TreeNode) -> bool: 25 | self.res = True 26 | def helper(root): 27 | if not root: 28 | return 0 29 | left = helper(root.left) + 1 30 | right = helper(root.right) + 1 31 | if abs(right - left) > 1: 32 | self.res = False 33 | return 0 34 | return max(left, right) 35 | helper(root) 36 | return self.res 37 | ''' 38 | 39 | class Solution(object): 40 | def depth(self, root): 41 | if root: 42 | return max(self.depth(root.left), self.depth(root.right))+1 43 | else: 44 | return False 45 | 46 | def isBalanced(self, root): 47 | """ 48 | :type root: TreeNode 49 | :rtype: bool 50 | """ 51 | if root: 52 | return abs(self.depth(root.right)-self.depth(root.left)) <= 1 and self.isBalanced(root.right) and self.isBalanced(root.left) 53 | else: 54 | return True 55 | -------------------------------------------------------------------------------- /384.md: -------------------------------------------------------------------------------- 1 | # 384. Shuffle an Array 2 | 3 | ## Intro 4 | 5 | Shuffle a set of numbers without duplicates. 6 | 7 | #### Example 8 | 9 | ``` 10 | // Init an array with set 1, 2, and 3. 11 | int[] nums = {1,2,3}; 12 | Solution solution = new Solution(nums); 13 | 14 | // Shuffle the array [1,2,3] and return its result. Any permutation of [1,2,3] must equally likely to be returned. 15 | solution.shuffle(); 16 | 17 | // Resets the array back to its original configuration [1,2,3]. 18 | solution.reset(); 19 | 20 | // Returns the random shuffling of array [1,2,3]. 21 | solution.shuffle(); 22 | ``` 23 | 24 | ## Thinking 25 | 26 | 随机排列数组。这里随机的方法是通过随机产生下标,进行交换值。 27 | 28 | ## Solution 29 | 30 | Python 31 | 32 | ```python 33 | import random 34 | class Solution(object): 35 | 36 | def __init__(self, nums): 37 | """ 38 | 39 | :type nums: List[int] 40 | :type size: int 41 | """ 42 | self.nums = nums 43 | 44 | 45 | def reset(self): 46 | """ 47 | Resets the array to its original configuration and return it. 48 | :rtype: List[int] 49 | """ 50 | return self.nums 51 | 52 | def shuffle(self): 53 | """ 54 | Returns a random shuffling of the array. 55 | :rtype: List[int] 56 | """ 57 | temp = self.nums[:] 58 | for i in range(len(temp)-1, 0, -1): 59 | j = random.randrange(0, i+1) 60 | temp[i], temp[j] = temp[j], temp[i] 61 | return temp 62 | 63 | 64 | # Your Solution object will be instantiated and called as such: 65 | # obj = Solution(nums) 66 | # param_1 = obj.reset() 67 | # param_2 = obj.shuffle() 68 | ``` -------------------------------------------------------------------------------- /173.md: -------------------------------------------------------------------------------- 1 | # 173. Binary Search Tree Iterator 2 | 3 | ## Intro 4 | 5 | Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the root node of a BST. 6 | 7 | Calling `next()` will return the next smallest number in the BST. 8 | 9 | **Note:** `next()` and `hasNext()` should run in average O(1) time and uses O(h) memory, where h is the height of the tree. 10 | 11 | ## Thinking 12 | 13 | 关于树的迭代器,因为要求小的时间和内存,所以考虑到用堆栈。因为h是树的高度,所以将二叉树转化为一维数组的方法不行,所以可以考虑记录所有的左儿子节点。主要需要思考的是next()的设计。因为记录了所有的左儿子,所以堆栈中最后一个就是最小的值,这时候pop出来,然后将这个节点的右儿子的左子树压入栈中,为下一次next访问做准备。 14 | 15 | ## Solution 16 | 17 | Python 18 | 19 | ```python 20 | # Definition for a binary tree node 21 | # class TreeNode(object): 22 | # def __init__(self, x): 23 | # self.val = x 24 | # self.left = None 25 | # self.right = None 26 | 27 | class BSTIterator(object): 28 | def __init__(self, root): 29 | """ 30 | :type root: TreeNode 31 | """ 32 | self.stack = [] 33 | while root: 34 | self.stack.append(root) 35 | root = root.left 36 | 37 | 38 | def hasNext(self): 39 | """ 40 | :rtype: bool 41 | """ 42 | return len(self.stack) > 0 43 | 44 | def next(self): 45 | """ 46 | :rtype: int 47 | """ 48 | node = self.stack.pop() 49 | t = node.right 50 | while t: 51 | self.stack.append(t) 52 | t = t.left 53 | return node.val 54 | 55 | 56 | 57 | # Your BSTIterator will be called like this: 58 | # i, v = BSTIterator(root), [] 59 | # while i.hasNext(): v.append(i.next()) 60 | ``` -------------------------------------------------------------------------------- /226.md: -------------------------------------------------------------------------------- 1 | #226. Invert Binary Tree 2 | 3 | ## Intro 4 | 5 | Invert a binary tree. 6 | 7 | ``` 8 | 4 9 | / \ 10 | 2 7 11 | / \ / \ 12 | 1 3 6 9 13 | ``` 14 | 15 | to 16 | 17 | ``` 18 | 4 19 | / \ 20 | 7 2 21 | / \ / \ 22 | 9 6 3 1 23 | ``` 24 | 25 | ## Thinking 26 | 27 | 这题据说还有个小插曲,关于Homebrew作者的。交换左右子树的常规思路是用递归,那么如何构造递归? 28 | 29 | 不难想到递归结束条件——当节点为空,下面要思考的是当节点不为空的时候。若节点不为空,那么就是交换左右子树。交换完了继续分别对左右子树进行递归。这样就能完成左右子树交换。 30 | 31 | 这里用到一个Python语言技巧: 32 | 33 | ```python 34 | root.left, root.right = root.right, root.left 35 | ``` 36 | 37 | 这种交换有人做过测试性能比使用一个临时变量效果要好点。 38 | 39 | ## Solution 40 | 41 | Python 42 | 43 | ```python 44 | 45 | # Definition for a binary tree node. 46 | # class TreeNode(object): 47 | # def __init__(self, x): 48 | # self.val = x 49 | # self.left = None 50 | # self.right = None 51 | 52 | class Solution(object): 53 | def invertTree(self, root): 54 | """ 55 | :type root: TreeNode 56 | :rtype: TreeNode 57 | """ 58 | if root != None: 59 | root.left, root.right = root.right, root.left 60 | self.invertTree(root.left) 61 | self.invertTree(root.right) 62 | return root 63 | return None 64 | 65 | ``` 66 | 67 | Runtime稍微少一点的代码: 68 | 69 | ```python 70 | 71 | class Solution(object): 72 | def invertTree(self, root): 73 | """ 74 | :type root: TreeNode 75 | :rtype: TreeNode 76 | """ 77 | if root: 78 | root.left, root.right = root.right, root.left 79 | self.invertTree(root.left) 80 | self.invertTree(root.right) 81 | return root 82 | ``` 83 | -------------------------------------------------------------------------------- /423.md: -------------------------------------------------------------------------------- 1 | # 423. Reconstruct Original Digits from English 2 | 3 | ## Intro 4 | 5 | Given a **non-empty** string containing an out-of-order English representation of digits `0-9`, output the digits in ascending order. 6 | 7 | #### Note 8 | 9 | 1. Input contains only lowercase English letters. 10 | 2. Input is guaranteed to be valid and can be transformed to its original digits. That means invalid inputs such as "abc" or "zerone" are not permitted. 11 | 3. Input length is less than 50,000. 12 | 13 | **Example 1:** 14 | 15 | ``` 16 | Input: "owoztneoer" 17 | Output: "012" 18 | ``` 19 | 20 | **Example 2:** 21 | 22 | ``` 23 | Input: "fviefuro" 24 | Output: "45" 25 | ``` 26 | 27 | ## Thinking 28 | 29 | 在打乱的字符串中,拼出数字。Note中保证了字符串的有效性,所以避免了很多麻烦。暴力求解肯定超时,所以需要思考这里面存在的规律。想到了用字母频率,因为不同的单词是又不同的字母拼得,有些单词存在唯一性。这里面有个有趣的规律,偶数单词都有唯一的单词,比如zero中唯一的是z,two中唯一的是w,four中唯一的是u,six中唯一的x,eight中唯一的是g,这时候就能计算出这几个单词的出现情况,剩下的单词可以用组合的方式计算出来。 30 | 31 | ## Solution 32 | 33 | Python 34 | 35 | ```python 36 | class Solution(object): 37 | def originalDigits(self, s): 38 | """ 39 | :type s: str 40 | :rtype: str 41 | """ 42 | dic = collections.Counter(s) 43 | num = [0 for i in xrange(10)] 44 | num[0] = dic['z'] 45 | num[2] = dic['w'] 46 | num[4] = dic['u'] 47 | num[6] = dic['x'] 48 | num[8] = dic['g'] 49 | num[1] = dic['o'] - num[4] - num[2] - num[0] 50 | num[3] = dic['r'] - num[0] - num[4] 51 | num[5] = dic['f'] - num[4] 52 | num[7] = dic['s'] - num[6] 53 | num[9] = dic['i'] - num[5] - num[6] - num[8] 54 | ret = '' 55 | for i, c in enumerate(num): 56 | ret += str(i) * c 57 | return ret 58 | ``` 59 | -------------------------------------------------------------------------------- /232.md: -------------------------------------------------------------------------------- 1 | # 232. Implement Queue using Stacks 2 | 3 | ## Intro 4 | 5 | Implement the following operations of a queue using stacks. 6 | 7 | * push(x) -- Push element x to the back of queue. 8 | * pop() -- Removes the element from in front of queue. 9 | * peek() -- Get the front element. 10 | * empty() -- Return whether the queue is empty. 11 | 12 | ###Notes 13 | 14 | * 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. 15 | * 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. 16 | * You may assume that all operations are valid (for example, no pop or peek operations will be called on an empty queue). 17 | 18 | ## Thinking 19 | 20 | Python这个有现成的实现,但题目中建议用堆栈来实现。然而好像还是有现成的做法。两个堆栈的实现也思考了,Python的实现就不细写了,因为对于队列顺序分两种,其实两种方法写都是对的。这里放上了很简单的实现。 21 | 22 | ## Solution 23 | 24 | Python 25 | 26 | 27 | ```python 28 | class Queue(object): 29 | def __init__(self): 30 | """ 31 | initialize your data structure here. 32 | """ 33 | self.queue = [] 34 | 35 | def push(self, x): 36 | """ 37 | :type x: int 38 | :rtype: nothing 39 | """ 40 | self.queue.append(x) 41 | 42 | def pop(self): 43 | """ 44 | :rtype: nothing 45 | """ 46 | self.queue.pop(0) 47 | 48 | def peek(self): 49 | """ 50 | :rtype: int 51 | """ 52 | return self.queue[0] 53 | 54 | def empty(self): 55 | """ 56 | :rtype: bool 57 | """ 58 | return len(self.queue) == 0 59 | ``` -------------------------------------------------------------------------------- /83.md: -------------------------------------------------------------------------------- 1 | # 83. Remove Duplicates from Sorted List 2 | 3 | ## Intro 4 | 5 | Given a sorted linked list, delete all duplicates such that each element appear only *once*. 6 | 7 | For example, 8 | Given `1->1->2`, return `1->2`. 9 | Given `1->1->2->3->3`, return `1->2->3`. 10 | 11 | ## Thinking 12 | 13 | 删除重复的节点,这个考察的是链表相关的知识。就是判断节点的下一个是否与该节点值不同,不同则指向下一个节点,相同则该节点的next指向该节点的next的next。 14 | 15 | ## Solution 16 | 17 | Python 18 | 19 | ```python 20 | # Definition for singly-linked list. 21 | # class ListNode(object): 22 | # def __init__(self, x): 23 | # self.val = x 24 | # self.next = None 25 | 26 | class Solution(object): 27 | def deleteDuplicates(self, head): 28 | """ 29 | :type head: ListNode 30 | :rtype: ListNode 31 | """ 32 | 33 | if not head or not head.next: 34 | return head 35 | p = head 36 | q = head.next 37 | while q: 38 | if p.val == q.val: 39 | p.next = None 40 | q = q.next 41 | continue 42 | p.next = q 43 | p = p.next 44 | q = q.next 45 | return head 46 | ``` 47 | 48 | Another 49 | 50 | ```python 51 | # Definition for singly-linked list. 52 | # class ListNode(object): 53 | # def __init__(self, x): 54 | # self.val = x 55 | # self.next = None 56 | class Solution(object): 57 | def deleteDuplicates(self, head): 58 | """ 59 | :type head: ListNode 60 | :rtype: ListNode 61 | """ 62 | p = head 63 | while head and p.next: 64 | if p.next.val == p.val: 65 | p.next = p.next.next 66 | else: 67 | p = p.next 68 | return head 69 | ``` 70 | -------------------------------------------------------------------------------- /394.md: -------------------------------------------------------------------------------- 1 | # 394. Decode String 2 | 3 | ## Intro 4 | 5 | Given an encoded string, return it's decoded string. 6 | 7 | The encoding rule is: `k[encoded_string]`, where the encoded_string inside the square brackets is being repeated exactly *k* times. Note that *k* is guaranteed to be a positive integer. 8 | 9 | You may assume that the input string is always valid; No extra white spaces, square brackets are well-formed, etc. 10 | 11 | Furthermore, you may assume that the original data does not contain any digits and that digits are only for those repeat numbers, k. For example, there won't be input like `3a` or `2[4]`. 12 | 13 | #### Examples 14 | 15 | ``` 16 | s = "3[a]2[bc]", return "aaabcbc". 17 | s = "3[a2[c]]", return "accaccacc". 18 | s = "2[abc]3[cd]ef", return "abcabccdcdcdef". 19 | ``` 20 | 21 | ## Thinking 22 | 23 | 这里需要用到堆栈,来保存之前的状态。当识别到数字时,需要记录下这个数,考虑到可能下一位也是数字,构成的是两位数甚至更多,所以可以在识别到第二个数时,需要将之前的数乘10然后再相加。当识别到`[`时,就要把之前的内容和数字压入栈内。当识别是字母时,将字母添加到一个临时变量中。当识别到`]`时,这时候就要将栈内的之前内容和之前数字取出,之前的内容拼接上取出的数字次数的临时变量。 24 | 25 | ## Solution 26 | 27 | Python 28 | 29 | ```python 30 | class Solution(object): 31 | def decodeString(self, s): 32 | """ 33 | :type s: str 34 | :rtype: str 35 | """ 36 | stack = [] 37 | curNum = 0 38 | ret = '' 39 | for c in s: 40 | if c == '[': 41 | stack.append(ret) 42 | stack.append(curNum) 43 | ret = '' 44 | curNum = 0 45 | elif c == ']': 46 | n = stack.pop() 47 | pre = stack.pop() 48 | ret = pre + n * ret 49 | elif c.isdigit(): 50 | curNum = curNum * 10 + int(c) 51 | else: 52 | ret += c 53 | return ret 54 | ``` -------------------------------------------------------------------------------- /205.md: -------------------------------------------------------------------------------- 1 | # 205. Isomorphic Strings 2 | 3 | ## Intro 4 | 5 | Given two strings **s** and **t**, determine if they are isomorphic. 6 | 7 | Two strings are isomorphic if the characters in **s** can be replaced to get **t**. 8 | 9 | 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. 10 | 11 | For example, 12 | Given `"egg"`, `"add"`, return true. 13 | 14 | Given `"foo"`, `"bar"`, return false. 15 | 16 | Given `"paper"`, `"title"`, return true. 17 | 18 | ## Thinking 19 | 20 | 判断字符串的构成规律是否相同,本题思路有好几个。其中一个比较巧妙,使用zip和set。zip是将对象中对应的元素打包成一个个tuple。那么,当是同构字符串时,打包的组合集合长度应该分别和两个数组的集合长度相同。另外也可以用find函数,比较两个数组的元素出现下标是否相同来解决这个问题。 21 | 22 | ## Solution 23 | 24 | Python 25 | 26 | ```python 27 | class Solution(object): 28 | def isIsomorphic(self, s, t): 29 | """ 30 | :type s: str 31 | :type t: str 32 | :rtype: bool 33 | """ 34 | return len(set(zip(s, t))) == len(set(s)) == len(set(t)) 35 | ``` 36 | 37 | ```python 38 | class Solution(object): 39 | def isIsomorphic(self, s, t): 40 | """ 41 | :type s: str 42 | :type t: str 43 | :rtype: bool 44 | """ 45 | return [s.find(i) for i in s] == [t.find(j) for j in t] 46 | ``` 47 | 48 | ```python 49 | class Solution(object): 50 | def isIsomorphic(self, s, t): 51 | """ 52 | :type s: str 53 | :type t: str 54 | :rtype: bool 55 | """ 56 | d1, d2 = [0 for _ in xrange(256)], [0 for _ in xrange(256)] 57 | for i in xrange(len(s)): 58 | if d1[ord(s[i])] != d2[ord(t[i])]: 59 | return False 60 | d1[ord(s[i])] = i+1 61 | d2[ord(t[i])] = i+1 62 | return True 63 | ``` -------------------------------------------------------------------------------- /292.md: -------------------------------------------------------------------------------- 1 | #292. Nim Game 2 | 3 | ## Intro 4 | 5 | You are playing the following Nim Game with your friend: There is a heap of stones on the table, each time one of you take turns to remove 1 to 3 stones. The one who removes the last stone will be the winner. You will take the first turn to remove the stones. 6 | 7 | Both of you are very clever and have optimal strategies for the game. Write a function to determine whether you can win the game given the number of stones in the heap. 8 | 9 | For example, if there are 4 stones in the heap, then you will never win the game: no matter 1, 2, or 3 stones you remove, the last stone will always be removed by your friend. 10 | 11 | ### Hint 12 | 13 | If there are 5 stones in the heap, could you figure out a way to remove the stones such that you will always be the winner? 14 | 15 | ## Thinking 16 | 17 | 首先,最笨的方法就是枚举测试。 18 | 19 | 一个石头的情况下,肯定只有先手必赢。二三也是。当第四个的石头的时候,因为自己一次拿不完,所以肯定是希望自己拿最少,尽量让总数 - 自己拿的石头数量仍然小于等于3。然而,当石头数量为4时,不管如何,都无法保证必赢。 20 | 21 | 这时,当石头数量为5时,在自己拿过石头以后,剩下的就是对手拿。如何保证自己必赢呢?那就是自己拿完以后,剩下的石头数量如果让自己拿必输。因为两个人博弈,换位思考一下。当自己拿完石头以后,自己的角色变成对手,只有自己必输的情况下,也就是对手必输的情况下自己才能赢。参考之前的会发现,如果自己拿完以后剩余数量为1, 2, 3时,那么肯定输。如果剩余数量为4,那么自己才会赢。即,在自己第一轮拿完石头以后,不管对手拿多少石头,剩余的石头数量总能保证属于自己必赢的范围。 22 | 23 | 例如数量为5块石头时, 24 | 25 | 5 - 1 = 4 // 所以只能选取这种方法,以下两种不选 26 | 27 | 5 - 2 = 3 28 | 29 | 5 - 3 = 2 30 | 31 | 例如数量为6块石头时,这时候第一次必须拿两个石头。 32 | 33 | 当石头数量为8时,会发现不管怎么拿都无法保证必赢,因为无法保证 34 | 35 | 这时候会发现,第一次的拿取方式就是保证剩余的为自己输的情况,也就是剩余为4的倍数。 36 | 37 | 所以最后就变成判断石块属是否为4的倍数,如果是,则不能保证必赢,如果不是,则能保证。 38 | 39 | ## Solution 40 | 41 | Python 42 | 43 | ```python 44 | class Solution(object): 45 | def canWinNim(self, n): 46 | """ 47 | :type n: int 48 | :rtype: bool 49 | """ 50 | if n % 4 == 0: 51 | return False 52 | else: 53 | return True 54 | ``` 55 | 56 | -------------------------------------------------------------------------------- /357.md: -------------------------------------------------------------------------------- 1 | # 357. Count Numbers with Unique Digits 2 | 3 | ## Intro 4 | 5 | Given a **non-negative** integer n, count all numbers with unique digits, x, where 0 ≤ x < 10^n. 6 | 7 | #### Example 8 | 9 | Given n = 2, return 91. (The answer should be the total numbers in the range of 0 ≤ x < 100, excluding `[11,22,33,44,55,66,77,88,99]`) 10 | 11 | #### Hint 12 | 13 | 1. A direct way is to use the backtracking approach. 14 | 2. Backtracking should contains three states which are (the current number, number of steps to get that number and a bitmask which represent which number is marked as visited so far in the current number). Start with state (0,0,0) and count all valid number till we reach number of steps equals to 10n. 15 | 3. This problem can also be solved using a dynamic programming approach and some knowledge of combinatorics. 16 | 4. Let f(k) = count of numbers with unique digits with length equals k. 17 | 5. f(1) = 10, ..., f(k) = 9 * 9 * 8 * ... (9 - k + 2) [The first factor is 9 because a number cannot start with 0]. 18 | 19 | ## Think 20 | 21 | 又是一道偏向数学的题目,其实就是求几个数字不重复的排列组合。当位数为k时,k位数中,各个位数字不重复的组合有f(k) = 9 * 9 * 8 * ... (9 - k + 2)种。那么思路就很清晰了。用一个数一直记录前k-1位时不重复的个数,再加上f(k)就是k位不重复的数字个数。 22 | 23 | ## Solution 24 | 25 | Python 26 | 27 | ```python 28 | class Solution(object): 29 | def countNumbersWithUniqueDigits(self, n): 30 | """ 31 | :type n: int 32 | :rtype: int 33 | """ 34 | pre = 1 35 | ret = 0 36 | acc = 1 37 | if n == 0:return 1 38 | for i in xrange(n): 39 | if i == 0: 40 | acc *= 9 41 | ret = pre + acc 42 | pre = ret 43 | continue 44 | acc *= (10 - i) 45 | pre = ret 46 | ret = acc + pre 47 | return ret 48 | ``` -------------------------------------------------------------------------------- /54.md: -------------------------------------------------------------------------------- 1 | # 54. Spiral Matrix 2 | 3 | ## Intro 4 | 5 | Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order. 6 | 7 | For example, 8 | 9 | Given the following matrix: 10 | 11 | ``` 12 | [ 13 | [ 1, 2, 3 ], 14 | [ 4, 5, 6 ], 15 | [ 7, 8, 9 ] 16 | ] 17 | ``` 18 | You should return `[1,2,3,6,9,8,7,4,5]`. 19 | 20 | ## Thinking 21 | 22 | 螺旋遍历一个二维数组,题目思路很清晰,主要考虑的就是边界的方向转换。这里的思路是从外往里进行循环访问,首先向右访问n-1个元素,再向下范围m-1个元素,接着再向左访问n-1个元素,之后向上访问m-1个元素。这时候圈子就需要缩小一点。 23 | 24 | ## Solution 25 | 26 | Python 27 | 28 | ```python 29 | class Solution(object): 30 | def spiralOrder(self, matrix): 31 | """ 32 | :type matrix: List[List[int]] 33 | :rtype: List[int] 34 | """ 35 | ret = [] 36 | x = len(matrix) # row 37 | if x == 0: 38 | return ret 39 | y = len(matrix[0]) # col 40 | i = j = -1 41 | while x > 1 and y > 1: 42 | i += 1 43 | j += 1 44 | for k in xrange(y-1): 45 | ret.append(matrix[i][j]) 46 | j += 1 47 | for k in xrange(x-1): 48 | ret.append(matrix[i][j]) 49 | i += 1 50 | for k in xrange(y-1): 51 | ret.append(matrix[i][j]) 52 | j -= 1 53 | for k in xrange(x-1): 54 | ret.append(matrix[i][j]) 55 | i -= 1 56 | x -= 2 57 | y -= 2 58 | i += 1 59 | j += 1 60 | if x == 1: 61 | for k in xrange(y): 62 | ret.append(matrix[i][j]) 63 | j += 1 64 | elif y == 1: 65 | for k in xrange(x): 66 | ret.append(matrix[i][j]) 67 | i += 1 68 | return ret 69 | ``` -------------------------------------------------------------------------------- /225.md: -------------------------------------------------------------------------------- 1 | # 225. Implement Stack using Queues 2 | 3 | ## Intro 4 | 5 | Implement the following operations of a stack using queues. 6 | 7 | * push(x) -- Push element x onto stack. 8 | * pop() -- Removes the element on top of the stack. 9 | * top() -- Get the top element. 10 | * empty() -- Return whether the stack is empty. 11 | 12 | #### Notes 13 | 14 | * 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. 15 | * 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. 16 | * You may assume that all operations are valid (for example, no pop or top operations will be called on an empty stack). 17 | 18 | ## Thinking 19 | 20 | 用队列来实现堆栈。主要需要思考的是pop,可以用循环pop 堆栈的长度-1次,将pop出来的元素继续添加进来,这样最左边的元素就是要pop出的。 21 | 22 | ## Solution 23 | 24 | Python 25 | 26 | ```python 27 | 28 | class Stack(object): 29 | def __init__(self): 30 | """ 31 | initialize your data structure here. 32 | """ 33 | self.stack = collections.deque([]) 34 | 35 | def push(self, x): 36 | """ 37 | :type x: int 38 | :rtype: nothing 39 | """ 40 | self.stack.append(x) 41 | 42 | 43 | def pop(self): 44 | """ 45 | :rtype: nothing 46 | """ 47 | for i in range(len(self.stack) - 1): 48 | self.stack.append(self.stack.popleft()) 49 | self.stack.popleft() 50 | 51 | def top(self): 52 | """ 53 | :rtype: int 54 | """ 55 | return self.stack[-1] 56 | 57 | def empty(self): 58 | """ 59 | :rtype: bool 60 | """ 61 | return len(self.stack) == 0 62 | ``` -------------------------------------------------------------------------------- /13.md: -------------------------------------------------------------------------------- 1 | # 13.Roman to Integer 2 | 3 | ## Intro 4 | 5 | Given a roman numeral, convert it to an integer. 6 | 7 | Input is guaranteed to be within the range from 1 to 3999. 8 | 9 | ## Thinking 10 | 11 | 首先需要了解罗马数字的规律 12 | 13 | 记数的方法: 14 | 15 | 1. 相同的数字连写,所表示的数等于这些数字相加得到的数,如 Ⅲ=3; 16 | 2. 小的数字在大的数字的右边,所表示的数等于这些数字相加得到的数,如 Ⅷ=8、Ⅻ=12; 17 | 3. 小的数字(限于 Ⅰ、X 和 C)在大的数字的左边,所表示的数等于大数减小数得到的数,如 Ⅳ=4、Ⅸ=9; 18 | 4. 在一个数的上面画一条横线,表示这个数增值 1,000 倍,如=5000。 19 | 20 | 最后一条本题不需要考虑。 21 | 22 | 个位数举例 23 | Ⅰ-1、Ⅱ-2、Ⅲ-3、Ⅳ-4、Ⅴ-5、Ⅵ-6、Ⅶ-7、Ⅷ-8、Ⅸ-9 24 | 25 | * 十位数举例 26 | 27 | Ⅹ-10、Ⅺ-11、Ⅻ-12、XIII-13、XIV-14、XV-15、XVI-16、XVII-17、XVIII-18、XIX-19、XX-20、XXI-21、XXII-22、XXIX-29、XXX-30、XXXIV-34、XXXV-35、XXXIX-39、XL-40、L-50、LI-51、LV-55、LX-60、LXV-65、LXXX-80、XC-90、XCIII-93、XCV-95、XCVIII-98、XCIX-99 28 | 29 | * 百位数举例 30 | 31 | C-100、CC-200、CCC-300、CD-400、D-500、DC-600、DCC-700、DCCC-800、CM-900、CMXCIX-999 32 | 33 | * 千位数举例 34 | 35 | M-1000、MC-1100、MCD-1400、MD-1500、MDC-1600、MDCLXVI-1666、MDCCCLXXXVIII-1888、MDCCCXCIX-1899、MCM-1900、MCMLXXVI-1976、MCMLXXXIV-1984、MCMXC-1990、MM-2000、MMMCMXCIX-3999 36 | 37 | 其实不看记数方法,根据后面的举例,也能发现这样一个规律。从右往左,如果这个位置的左边一个数大于等于这个数,那么就加上左边的这个数,如果小于就减去,然后往左移一个继续循环。 38 | 39 | 比如 XCIX ,首先加上末尾的值, 然后因为左边一个I小于X, 所以减去I的值。接着在I的位置,因为I的左边C大于I, 所以加上C的值。继续所以减去X的值。 40 | 41 | 42 | ## Solution 43 | 44 | Python 45 | 46 | ```python 47 | class Solution(object): 48 | def romanToInt(self, s): 49 | """ 50 | :type s: str 51 | :rtype: int 52 | """ 53 | value = {'M':1000,'D':500,'C':100,'L':50,'X':10,'V':5,'I':1} 54 | ret = 0 55 | length = len(s) 56 | 57 | ret += value[s[length - 1]] 58 | 59 | for i in range(length - 1): 60 | if value[s[length - i - 2]] >= value[s[length - i - 1]]: 61 | ret += value[s[length - i - 2]] 62 | else: 63 | ret -= value[s[length - i - 2]] 64 | return ret 65 | ``` 66 | -------------------------------------------------------------------------------- /190.md: -------------------------------------------------------------------------------- 1 | # 190. Reverse Bits 2 | 3 | ## Intro 4 | 5 | Reverse bits of a given 32 bits unsigned integer. 6 | 7 | For example, given input 43261596 (represented in binary as **00000010100101000001111010011100**), return 964176192 (represented in binary as **00111001011110000010100101000000**). 8 | 9 | ## Thinking 10 | 11 | 这题有两种思路,首先我的思路是比较简单的方法,用字符串,这种方用Python很好实现。另外参考了些资料,分析一下另一种思路——位操作。使用的思想是分治原理。 12 | 13 | 按照按位操作的步骤,假设n = 00000010100101000001111010011100(二进制数) 14 | 15 | 第一步是前16位和后16位交换 16 | 17 | n = (n >> 16) | (n << 16) = 0001111010011100 0000001010010100 18 | 19 | 第二步每8位一组,进行交换 20 | 21 | n = ((n & 0xff00ff00) >> 8) | ((n & 0x00ff00ff) << 8) = 10011100 00011110 10010100 00000010 22 | 23 | 第三步每4位一组,进行交换 24 | 25 | n = ((n & 0xf0f0f0f0) >> 4) | ((n & 0x0f0f0f0f) << 4) = 1100 1001 1110 0001 0100 1001 0010 0000 26 | 27 | 第四步每2位一组,进行交换 28 | 29 | n = ((n & 0xcccccccc) >> 2) | ((n & 0x33333333) << 2) = 00 11 01 10 10 11 01 00 00 01 01 10 10 00 00 00 30 | 31 | 第五步每一位一组,进行交换 32 | 33 | n = ((n & 0xaaaaaaaa) >> 1) | ((n & 0x55555555) << 1) = 0 0 1 1 1 0 0 1 0 1 1 1 1 0 0 0 0 0 1 0 1 0 0 1 0 1 0 0 0 0 0 0 34 | 35 | 最终这个就是结果。 36 | 37 | 38 | ## Solution 39 | 40 | Python 41 | 42 | Use str 43 | 44 | ```python 45 | class Solution(object): 46 | def reverseBits(self, n): 47 | """ 48 | :type n: int 49 | :rtype: int 50 | """ 51 | return int((str(bin(n))[2:].zfill(32))[::-1], base=2) 52 | ``` 53 | 54 | Use bit operation 55 | 56 | ```python 57 | class Solution(object): 58 | def reverseBits(self, n): 59 | """ 60 | :type n: int 61 | :rtype: int 62 | """ 63 | n = (n >> 16) | (n << 16) 64 | n = ((n & 0xff00ff00) >> 8) | ((n & 0x00ff00ff) << 8) 65 | n = ((n & 0xf0f0f0f0) >> 4) | ((n & 0x0f0f0f0f) << 4) 66 | n = ((n & 0xcccccccc) >> 2) | ((n & 0x33333333) << 2) 67 | n = ((n & 0xaaaaaaaa) >> 1) | ((n & 0x55555555) << 1) 68 | return n 69 | ``` 70 | -------------------------------------------------------------------------------- /237.md: -------------------------------------------------------------------------------- 1 | #237.Delete Node in a Linked List 2 | 3 | ## Intro 4 | 5 | Write a function to delete a node (except the tail) in a singly linked list, given only access to that node. 6 | 7 | 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. 8 | 9 | ## Thinking 10 | 11 | 删除单链表的某个节点算是数据结构比较基础的问题了。因为这里只是传入了要删节点,所以如果想通过直接修改要删节点的前驱节点的后继引用会比较麻烦。这里使用的方法是将要删节点的next节点值赋给这个要删节点,将该节点的next引用向后引用两次。其实就是复制了要删节点的next节点,将要删节点的next节点删去。 12 | 13 | 我用图的方式,来演示一个例子。 14 | 15 | 首先是一条单链表: 16 | 17 | ``` 18 | +-----+ +-----+ +-----+ +-----+ +-----+ 19 | | 1 +--> 2 +--> 3 +--> 4 +--> 5 | 20 | +-----+ +-----+ +-----+ +-----+ +-----+ 21 | 22 | ``` 23 | 24 | 因为要删除节点3,所以先将节点4的值拷给节点3: 25 | 26 | ``` 27 | +-----+ +-----+ +-----+ +-----+ +-----+ 28 | | 1 +--> 2 +--> 4 +--> 4 +--> 5 | 29 | +-----+ +-----+ +-----+ +-----+ +-----+ 30 | 31 | ``` 32 | 33 | 之后将节点3指向节点5: 34 | 35 | ``` 36 | +-----------------+ 37 | | | 38 | +-----+ +-----+ +--+--+ +-----+ +--v--+ 39 | | 1 +--> 2 +--> 4 |x-> 4 +--> 5 | 40 | +-----+ +-----+ +-----+ +-----+ +-----+ 41 | 42 | ``` 43 | 44 | 所以就得到了删除后的链表 45 | 46 | ``` 47 | +-----+ +-----+ +-----+ +-----+ 48 | | 1 +--> 2 +--> 4 +--> 5 | 49 | +-----+ +-----+ +-----+ +-----+ 50 | ``` 51 | 52 | ## Solution 53 | Python 54 | 55 | ```python 56 | # Definition for singly-linked list. 57 | # class ListNode(object): 58 | # def __init__(self, x): 59 | # self.val = x 60 | # self.next = None 61 | 62 | class Solution(object): 63 | def deleteNode(self, node): 64 | """ 65 | :type node: ListNode 66 | :rtype: void Do not return anything, modify node in-place instead. 67 | """ 68 | node.val = node.next.val 69 | node.next = node.next.next 70 | ``` -------------------------------------------------------------------------------- /235.md: -------------------------------------------------------------------------------- 1 | # 235. Lowest Common Ancestor of a Binary Search Tree 2 | 3 | ## Intro 4 | 5 | Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST. 6 | 7 | According to the [definition of LCA on Wikipedia](https://en.wikipedia.org/wiki/Lowest_common_ancestor): “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**).” 8 | 9 | ``` 10 | _______6______ 11 | / \ 12 | ___2__ ___8__ 13 | / \ / \ 14 | 0 _4 7 9 15 | / \ 16 | 3 5 17 | ``` 18 | 19 | 20 | ## Thinking 21 | 22 | 首先回顾一下BST的概念: 23 | 24 | 二叉排序树或者是一棵空树,或者是具有下列性质的二叉树: 25 | 26 | 1. 若左子树不空,则左子树上所有结点的值均小于它的根结点的值; 27 | 2. 若右子树不空,则右子树上所有结点的值均大于它的根结点的值; 28 | 3. 左、右子树也分别为二叉排序树; 29 | 4. 没有键值相等的节点。 30 | 31 | 所以,查找两个node的最早的公共祖先,分三种情况: 32 | 33 | 1. 如果两个node在root的两边,那么最早的公共祖先就是root。 34 | 2. 如果两个node在root的左边,那么把root.left作为root,再递归。 35 | 3. 如果两个node在root的右边,那么把root.right作为root,再递归。 36 | 37 | 38 | 39 | ## Solution 40 | 41 | Python 42 | 43 | ```python 44 | # Definition for a binary tree node. 45 | # class TreeNode(object): 46 | # def __init__(self, x): 47 | # self.val = x 48 | # self.left = None 49 | # self.right = None 50 | 51 | class Solution(object): 52 | def lowestCommonAncestor(self, root, p, q): 53 | """ 54 | :type root: TreeNode 55 | :type p: TreeNode 56 | :type q: TreeNode 57 | :rtype: TreeNode 58 | """ 59 | if (p.val <= root.val <= q.val or q.val <= root.val <= p.val): 60 | return root.val 61 | elif (p.val < root.val and q.val < root.val): 62 | return self.lowestCommonAncestor(root.left, p, q) 63 | else: 64 | return self.lowestCommonAncestor(root.right, p, q) 65 | ``` -------------------------------------------------------------------------------- /6.md: -------------------------------------------------------------------------------- 1 | # 6. ZigZag Conversion 2 | 3 | ## Intro 4 | 5 | The string `"PAYPALISHIRING"` is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility) 6 | 7 | ``` 8 | P A H N 9 | A P L S I I G 10 | Y I R 11 | ``` 12 | 13 | And then read line by line: `"PAHNAPLSIIGYIR"` 14 | 15 | Write the code that will take a string and make this conversion given a number of rows: 16 | 17 | ``` 18 | string convert(string text, int nRows); 19 | ``` 20 | `convert("PAYPALISHIRING", 3)` should return `"PAHNAPLSIIGYIR"`. 21 | 22 | ## Think 23 | 24 | 将字符串按照从上到下从左到右Z字型排列,最后从上到下横排记录。那么可以用一个死方法,建numRows个list,每个list中有个空字符串,然后从上到下从左到右开始记录。可以画出一个图。 25 | 26 | ``` 27 | Δ=2n-2 1 2n-1 4n-3 28 | Δ= 2 2n-2 2n 4n-4 4n-2 29 | Δ= 3 2n-3 2n+1 4n-5 . 30 | Δ= . . . . . 31 | Δ= . n+2 . 3n . 32 | Δ= n-1 n+1 3n-3 3n-1 5n-5 33 | Δ=2n-2 n 3n-2 5n-4 34 | ``` 35 | 这里要注意,每当处于第一行和最后一行时,填充方向需要改变。有个细节要注意的是如果numRows为1或者大于s的长度,只需直接返回s。 36 | 37 | ## Solution 38 | 39 | Python 40 | 41 | ```python 42 | class Solution(object): 43 | def convert(self, s, numRows): 44 | """ 45 | :type s: str 46 | :type numRows: int 47 | :rtype: str 48 | """ 49 | if numRows == 1 or numRows >= len(s): 50 | return s 51 | rows = [''] * numRows 52 | index = 0 53 | step = -1 54 | for c in s: 55 | rows[index] += c 56 | if index == 0 or index == numRows - 1: 57 | step = -step 58 | index += step 59 | return ''.join(rows) 60 | ``` -------------------------------------------------------------------------------- /382.md: -------------------------------------------------------------------------------- 1 | # 382. Linked List Random Node 2 | 3 | ## Intro 4 | 5 | Given a singly linked list, return a random node's value from the linked list. Each node must have the same probability of being chosen. 6 | 7 | #### Follow up 8 | 9 | What if the linked list is extremely large and its length is unknown to you? Could you solve this efficiently without using extra space? 10 | 11 | #### Example 12 | 13 | ``` 14 | // Init a singly linked list [1,2,3]. 15 | ListNode head = new ListNode(1); 16 | head.next = new ListNode(2); 17 | head.next.next = new ListNode(3); 18 | Solution solution = new Solution(head); 19 | 20 | // getRandom() should return either 1, 2, or 3 randomly. Each element should have equal probability of returning. 21 | solution.getRandom(); 22 | ``` 23 | 24 | ## Thinking 25 | 26 | 这题比较抽象,随机返回一个节点。这里用到的小技巧是在遍历的时候算上概率,可以做到一次遍历就能得出结果。 27 | 28 | ## Solution 29 | 30 | Python 31 | 32 | ```python 33 | # Definition for singly-linked list. 34 | # class ListNode(object): 35 | # def __init__(self, x): 36 | # self.val = x 37 | # self.next = None 38 | 39 | class Solution(object): 40 | 41 | def __init__(self, head): 42 | """ 43 | @param head The linked list's head. 44 | Note that the head is guaranteed to be not null, so it contains at least one node. 45 | :type head: ListNode 46 | """ 47 | self.head = head 48 | 49 | 50 | def getRandom(self): 51 | """ 52 | Returns a random node's value. 53 | :rtype: int 54 | """ 55 | result, node, index = self.head, self.head.next, 1 56 | while node: 57 | if random.randint(0, index) is 0: 58 | result = node 59 | node = node.next 60 | index += 1 61 | return result.val 62 | 63 | 64 | # Your Solution object will be instantiated and called as such: 65 | # obj = Solution(head) 66 | # param_1 = obj.getRandom() 67 | ``` -------------------------------------------------------------------------------- /318.md: -------------------------------------------------------------------------------- 1 | # 318. Maximum Product of Word Lengths 2 | 3 | ## Intro 4 | 5 | Given a string array `words`, find the maximum value of `length(word[i]) * length(word[j])` where the two words do not share common letters. You may assume that each word will contain only lower case letters. If no such two words exist, return 0. 6 | 7 | **Example 1:** 8 | 9 | Given `["abcw", "baz", "foo", "bar", "xtfn", "abcdef"]` 10 | 11 | Return `16` 12 | 13 | The two words can be `"abcw", "xtfn"`. 14 | 15 | **Example 2:** 16 | 17 | Given `["a", "ab", "abc", "d", "cd", "bcd", "abcd"]` 18 | 19 | Return `4` 20 | 21 | The two words can be `"ab", "cd"`. 22 | 23 | **Example 3:** 24 | 25 | Given `["a", "aa", "aaa", "aaaa"]` 26 | 27 | Return `0` 28 | 29 | No such pair of words. 30 | 31 | ## Think 32 | 33 | 最开始想到的方法就是循环遍历,通过优化,可以被Accept。这时,通过参考其他方法,发现了一个很高效的算法。是用字典和位操作,建立的字典关于字母和长度。关于字母,可以用二进制来代表。`mask |= (1 << (ord(c) - 97))`这句是将字母序列转化为二进制数的关键一步。 34 | 35 | ## Solution 36 | 37 | ```python 38 | def maxProduct(words): 39 | """ 40 | :type words: List[str] 41 | :rtype: int 42 | """ 43 | # ret = 0 44 | # while words: 45 | # currWorld = set(words[0]) 46 | # currLen = len(words[0]) 47 | # words = words[1:] 48 | # for w in words: 49 | # for c in currWorld: 50 | # if c in w: 51 | # break 52 | # else: 53 | # ret = max(ret,len(w) * currLen) 54 | # return ret 55 | ``` 56 | 57 | Another 58 | 59 | ```python 60 | class Solution(object): 61 | def maxProduct(self, words): 62 | """ 63 | :type words: List[str] 64 | :rtype: int 65 | """ 66 | d = {} 67 | for w in words: 68 | mask = 0 69 | for c in set(w): 70 | mask |= (1 << (ord(c) - 97)) 71 | d[mask] = max(d.get(mask, 0), len(w)) 72 | return max([d[x] * d[y] for x in d for y in d if not x & y] or [0]) 73 | ``` -------------------------------------------------------------------------------- /Leetcode/102.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class Solution(object): 9 | def levelOrder(self, root): 10 | """ 11 | :type root: TreeNode 12 | :rtype: List[List[int]] 13 | """ 14 | if not root: 15 | return [] 16 | 17 | ret = [] 18 | queue = [root] 19 | 20 | while queue: 21 | level_size = len(queue) 22 | current_level = [] 23 | for _ in range(level_size): 24 | node = queue.pop(0) 25 | current_level.append(node.val) 26 | if node.left: 27 | queue.append(node.left) 28 | if node.right: 29 | queue.append(node.right) 30 | ret.append(current_level) 31 | 32 | return ret 33 | 34 | 35 | ''' 36 | class Solution: 37 | def levelOrder(self, root): 38 | """ 39 | :type root: TreeNode 40 | :rtype: List[List[int]] 41 | """ 42 | def helper(node, level): 43 | if not node: 44 | return 45 | else: 46 | ret[level-1].append(node.val) 47 | if len(ret) == level: # 遍历到新层时,只有最左边的结点使得等式成立 48 | ret.append([]) 49 | helper(node.left, level+1) 50 | helper(node.right, level+1) 51 | ret = [[]] 52 | helper(root, 1) 53 | return ret[:-1] 54 | ''' 55 | 56 | ''' 57 | class Solution(object): 58 | def levelOrder(self, root): 59 | """ 60 | :type root: TreeNode 61 | :rtype: List[List[int]] 62 | """ 63 | ret = [] 64 | T = [root] 65 | while T and root: 66 | ret.append([x.val for x in T]) 67 | T = [p for n in T for p in (n.left, n.right) if p] 68 | return ret 69 | ''' -------------------------------------------------------------------------------- /94.md: -------------------------------------------------------------------------------- 1 | # 94. Binary Tree Inorder Traversal 2 | 3 | ## Intro 4 | 5 | 6 | Given a binary tree, return the preorder traversal of its nodes' values. 7 | 8 | For example: 9 | 10 | Given binary tree `[1,null,2,3]`, 11 | 12 | ``` 13 | 1 14 | \ 15 | 2 16 | / 17 | 3 18 | ``` 19 | 20 | return `[1,3,2]`. 21 | 22 | ## Think 23 | 24 | 中序遍历。同样,考虑递归方法和非递归方法。递归方法和先序遍历类似,只需要改变一下访问节点和记录的顺序即可。非递归也是使用堆栈。 25 | 26 | ## Solution 27 | 28 | Recursive 29 | 30 | ```python 31 | # Definition for a binary tree node. 32 | # class TreeNode(object): 33 | # def __init__(self, x): 34 | # self.val = x 35 | # self.left = None 36 | # self.right = None 37 | 38 | class Solution(object): 39 | def inorderTraversal(self, root): 40 | """ 41 | :type root: TreeNode 42 | :rtype: List[int] 43 | """ 44 | ret = [] 45 | def traverse(root): 46 | if not root: 47 | return 48 | traverse(root.left) 49 | ret.append(root.val) 50 | traverse(root.right) 51 | 52 | traverse(root) 53 | return ret 54 | ``` 55 | 56 | Iterative 57 | ``` 58 | # Definition for a binary tree node. 59 | # class TreeNode(object): 60 | # def __init__(self, x): 61 | # self.val = x 62 | # self.left = None 63 | # self.right = None 64 | 65 | class Solution(object): 66 | def inorderTraversal(self, root): 67 | """ 68 | :type root: TreeNode 69 | :rtype: List[int] 70 | """ 71 | if not root: 72 | return [] 73 | 74 | ret = [] 75 | stack = [] 76 | 77 | while root or stack: 78 | while root: 79 | stack.append(root) 80 | root = root.left 81 | if stack: 82 | root = stack.pop() 83 | ret.append(root.val) 84 | root = root.right 85 | return ret 86 | ``` -------------------------------------------------------------------------------- /299.md: -------------------------------------------------------------------------------- 1 | # 299. Bulls and Cows 2 | 3 | ## Intro 4 | 5 | You are playing the following [Bulls and Cows](https://en.wikipedia.org/wiki/Bulls_and_Cows) game with your friend: You write down a number and ask your friend to guess what the number is. Each time your friend makes a guess, you provide a hint that indicates how many digits in said guess match your secret number exactly in both digit and position (called "bulls") and how many digits match the secret number but locate in the wrong position (called "cows"). Your friend will use successive guesses and hints to eventually derive the secret number. 6 | 7 | For example: 8 | 9 | ``` 10 | Secret number: "1807" 11 | Friend's guess: "7810" 12 | ``` 13 | Hint: `1` bull and `3` cows. (The bull is `8`, the cows are `0`, `1` and `7`.) 14 | Write a function to return a hint according to the secret number and friend's guess, use A to indicate the bulls and B to indicate the cows. In the above example, your function should return `"1A3B"`. 15 | 16 | Please note that both secret number and friend's guess may contain duplicate digits, for example: 17 | 18 | ``` 19 | Secret number: "1123" 20 | Friend's guess: "0111" 21 | ``` 22 | 23 | In this case, the 1st 1 in friend's guess is a bull, the 2nd or 3rd 1 is a cow, and your function should return "1A1B". 24 | You may assume that the secret number and your friend's guess only contain digits, and their lengths are always equal. 25 | 26 | ## Think 27 | 28 | 对于求bulls这个不是很难,使用列表生成器进行遍历判断即可。而cows就要麻烦点,首先需要计算出数字交集所填的位置个数,再减去填正确的个数,剩下的就是错误的个数。 29 | 30 | ## Solution 31 | 32 | Python 33 | 34 | ```python 35 | class Solution(object): 36 | def getHint(self, secret, guess): 37 | """ 38 | :type secret: str 39 | :type guess: str 40 | :rtype: str 41 | """ 42 | z = zip(secret, guess) 43 | same = [x for x, y in z if x == y] 44 | A = len(same) 45 | B = sum(min(secret.count(n), guess.count(n)) for n in '0123456789') - A 46 | return str(A)+'A'+str(B)+'B' 47 | ``` -------------------------------------------------------------------------------- /144.md: -------------------------------------------------------------------------------- 1 | # 144. Binary Tree Preorder Traversal 2 | 3 | ## Intro 4 | 5 | Given a binary tree, return the preorder traversal of its nodes' values. 6 | 7 | For example: 8 | 9 | Given binary tree `{1,#,2,3}`, 10 | 11 | ``` 12 | 1 13 | \ 14 | 2 15 | / 16 | 3 17 | ``` 18 | 19 | return `[1,2,3]`. 20 | 21 | ## Think 22 | 23 | 先序遍历。考虑递归方法和非递归方法。先序遍历就是先访问根节点,再访问左子树,之后访问右子树。递归的方法就是这个思路。而迭代的方法就是用一个堆栈来保存访问左子树的路径,通过pop返回再遍历右子树。 24 | 25 | ## Solution 26 | 27 | Recursive 28 | 29 | ```python 30 | # Definition for a binary tree node. 31 | # class TreeNode(object): 32 | # def __init__(self, x): 33 | # self.val = x 34 | # self.left = None 35 | # self.right = None 36 | 37 | class Solution(object): 38 | def preorderTraversal(self, root): 39 | """ 40 | :type root: TreeNode 41 | :rtype: List[int] 42 | """ 43 | ret = [] 44 | def traverse(root): 45 | if not root: 46 | return 47 | ret.append(root.val) 48 | traverse(root.left) 49 | traverse(root.right) 50 | 51 | traverse(root) 52 | return ret 53 | ``` 54 | Iterative 55 | ``` 56 | # Definition for a binary tree node. 57 | # class TreeNode(object): 58 | # def __init__(self, x): 59 | # self.val = x 60 | # self.left = None 61 | # self.right = None 62 | 63 | class Solution(object): 64 | def preorderTraversal(self, root): 65 | """ 66 | :type root: TreeNode 67 | :rtype: List[int] 68 | """ 69 | if not root: 70 | return [] 71 | 72 | ret = [] 73 | stack = [] 74 | 75 | while root or stack: 76 | while root: 77 | ret.append(root.val) 78 | stack.append(root) 79 | root = root.left 80 | if stack: 81 | root = stack.pop() 82 | root = root.right 83 | return ret 84 | ``` -------------------------------------------------------------------------------- /350.md: -------------------------------------------------------------------------------- 1 | # 350. Intersection of Two Arrays II 2 | 3 | ## Intro 4 | 5 | Given two arrays, write a function to compute their intersection. 6 | 7 | #### Example 8 | 9 | Given nums1 = `[1, 2, 2, 1]`, nums2 = `[2, 2]`, return `[2, 2]`. 10 | 11 | #### Note 12 | 13 | Each element in the result should appear as many times as it shows in both arrays. 14 | The result can be in any order. 15 | 16 | #### Follow up 17 | 18 | * What if the given array is already sorted? How would you optimize your algorithm? 19 | * What if nums1's size is small compared to num2's size? Which algorithm is better? 20 | * What if elements of nums2 are stored on disk, and the memory is limited such that you cannot load all elements into the memory at once? 21 | 22 | ## Think 23 | 24 | 和349类似,但思路上选择了不一样的方式,如果说之前是求交集,交集的前提是用set,然而这里只是返回相同的元素,那么就可能存在相同元素多次出现。首先排序,将两个list里的元素进行排序,分别遍历两个list,如果一样,就添加到结果list中。这里稍微思考了一下Follow up的内容。如果已经排序,那么可以省去排序过程。第二个如果nums1的元素个数与nums2相差几个数量级,那么可以只是遍历nums1,判断nums1的元素是否在nums2里面,时间复杂度为O(len(nums1)*len(nums2))->O(MN).第三个问题可以用指针,这里python我是用的下标与异常来模拟list非常大,而不是去求list的长度,直接用下标一个个访问。 25 | 26 | ## Solution 27 | 28 | Python 29 | 30 | ```python 31 | class Solution(object): 32 | def intersect(self, nums1, nums2): 33 | """ 34 | :type nums1: List[int] 35 | :type nums2: List[int] 36 | :rtype: List[int] 37 | """ 38 | index1 = index2 = 0 39 | ret = [] 40 | nums1 = sorted(nums1) 41 | nums2 = sorted(nums2) 42 | count = 0 43 | try: 44 | while (nums1[index1] is not None) and (nums2[index2] is not None): 45 | count += 1 46 | if nums1[index1] < nums2[index2]: 47 | index1 += 1 48 | elif nums1[index1] > nums2[index2]: 49 | index2 += 1 50 | else: 51 | ret.append(nums1[index1]) 52 | index1 += 1 53 | index2 += 1 54 | except IndexError: 55 | return ret 56 | ``` 57 | -------------------------------------------------------------------------------- /238.md: -------------------------------------------------------------------------------- 1 | # 238. Product of Array Except Self 2 | 3 | ## Intro 4 | 5 | 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]`. 6 | 7 | Solve it **without division** and in O(n). 8 | 9 | For example, given `[1,2,3,4]`, return `[24,12,8,6]`. 10 | 11 | ## Think 12 | 13 | 为了达到O(n),就不能遍历每个元素的时候,求出其他元素的乘积这种暴力算法。那么可以先求出整个的积,用他除以每个元素,就是剩余元素的积。需要注意的细节是,如果nums里有0,要知道0不能做除数。所以这里要讨论些情况。当0的个数只有1个,那么返回的list应该是只有在0的位置,结果是其他非零的积,其余的都为0。如果0的个数大于等于2,那么返回的全为0。 14 | 15 | 另外还有一种解法,不需要分情况,但思路很清晰。用一个list保存从左到右遍历记录第二个到第n-1个的乘积,这时list的最后一个元素就是nums[0:-1]的乘积。这个list对应了nums每个元素的前面元素的乘积。 16 | 17 | 例如 18 | 19 | nums = [1, 2, 3, 4] 20 | 21 | ret = [1, 1, 2, 6] 22 | 23 | 那么从右往左遍历ret时, 只要乘上nums右边的积,就可以求出结果。所以用temp保存右边乘到左边的积。 24 | 25 | ## Solution 26 | 27 | Python 28 | 29 | ```python 30 | class Solution(object): 31 | def productExceptSelf(self, nums): 32 | """ 33 | :type nums: List[int] 34 | :rtype: List[int] 35 | """ 36 | s = 1 37 | for c in nums: 38 | if c != 0: 39 | s *= c 40 | if 0 not in nums: 41 | return [s / x for x in nums] 42 | elif nums.count(0) >= 2 : 43 | return len(nums) * [0] 44 | else: 45 | ret = [] 46 | for i in nums: 47 | if i != 0: 48 | ret += [0] 49 | else: 50 | ret += [s] 51 | return ret 52 | ``` 53 | 54 | ```python 55 | class Solution(object): 56 | def productExceptSelf(self, nums): 57 | """ 58 | :type nums: List[int] 59 | :rtype: List[int] 60 | """ 61 | length = len(nums) 62 | ret = [1]*length 63 | for i in range(1,length): 64 | ret[i] = ret[i-1]*nums[i-1] 65 | temp = 1 66 | for j in xrange(length-1, -1, -1): 67 | ret[j] = ret[j]*temp 68 | temp = temp * nums[j] 69 | return ret 70 | ``` -------------------------------------------------------------------------------- /155.md: -------------------------------------------------------------------------------- 1 | # 155. Min Stack 2 | 3 | ## Intro 4 | 5 | Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. 6 | 7 | * push(x) -- Push element x onto stack. 8 | * pop() -- Removes the element on top of the stack. 9 | * top() -- Get the top element. 10 | * getMin() -- Retrieve the minimum element in the stack. 11 | 12 | #### Example 13 | 14 | ``` 15 | MinStack minStack = new MinStack(); 16 | minStack.push(-2); 17 | minStack.push(0); 18 | minStack.push(-3); 19 | minStack.getMin(); --> Returns -3. 20 | minStack.pop(); 21 | minStack.top(); --> Returns 0. 22 | minStack.getMin(); --> Returns -2. 23 | ``` 24 | 25 | ## Think 26 | 27 | 考虑到这是Min Stack 最小堆,一开始的想法是正常的堆再配上一个min保存最小的值,然而,在pop时,最小值需要退回到之前一个值。考虑到建立min的list需要额外空间,这里换了另外一种思路。stack里每次添加的是一个tuple,一个是x,另一个是堆的最小值,这样getMin()的时间复杂度就降到了O(1). 28 | 29 | ## Solution 30 | 31 | Python 32 | 33 | ```python 34 | class MinStack(object): 35 | 36 | def __init__(self): 37 | """ 38 | initialize your data structure here. 39 | """ 40 | self.stack= [] 41 | self.min = None 42 | 43 | 44 | def push(self, x): 45 | """ 46 | :type x: int 47 | :rtype: void 48 | """ 49 | if not self.stack: 50 | self.stack.append((x,x)) 51 | else: 52 | self.stack.append((x, min(x, self.stack[-1][1]))) 53 | 54 | def pop(self): 55 | """ 56 | :rtype: void 57 | """ 58 | x = self.stack.pop() 59 | 60 | 61 | def top(self): 62 | """ 63 | :rtype: int 64 | """ 65 | if self.stack: 66 | return self.stack[-1][0] 67 | else: 68 | return None 69 | 70 | def getMin(self): 71 | """ 72 | :rtype: int 73 | """ 74 | if self.stack: 75 | return self.stack[-1][1] 76 | else: 77 | return None 78 | 79 | 80 | 81 | # Your MinStack object will be instantiated and called as such: 82 | # obj = MinStack() 83 | # obj.push(x) 84 | # obj.pop() 85 | # param_3 = obj.top() 86 | # param_4 = obj.getMin() 87 | ``` -------------------------------------------------------------------------------- /260.md: -------------------------------------------------------------------------------- 1 | #260. Single Number III 2 | 3 | ## Intro 4 | 5 | Given an array of numbers `nums`, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once. 6 | 7 | For example: 8 | 9 | Given nums = `[]1, 2, 1, 3, 2, 5]`, return `[3, 5]`. 10 | 11 | ###Note 12 | 13 | 1. The order of the result is not important. So in the above example, `[5, 3]` is also correct. 14 | 2. Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity? 15 | 16 | ## Thinking 17 | 18 | 一开始说实话只想到了最基础的方法,还需要一个`collections.defaultdict(list)`这个高级用法。以下代码看一下就能懂什么意思了。 19 | 20 | ```python 21 | class Solution(object): 22 | def singleNumber(self, nums): 23 | """ 24 | :type nums: List[int] 25 | :rtype: List[int] 26 | """ 27 | nlist = collections.defaultdict(list) 28 | result = [] 29 | for num in nums: 30 | nlist[num].append(1) 31 | for key in nlist: 32 | if len(nlist[key]) == 1: 33 | result.append(key) 34 | 35 | return result 36 | ``` 37 | 38 | 然而,在查这道题时, 有一些比较高级的思路,让我研究了一会儿。 39 | 和`Single Number I`类似,假设要找出的数为 `a` 和 `b`.`nums`的异或结果为 `x = a ^ b`.关键就是如何区分开`a`和`b`。考虑到`a`和`b`肯定不相同,所以`x`肯定不为0.也就是说`a`和`b`肯定存在一位,使得在它们中的某个数中是 0,而在另一个数中是 1。 40 | 关于找这一位,在有的资料是任取`x`中的一个二进制位,也有的说找 `x` 中最低位的 1。这里就以后者来介绍这个方法。关于找最低位1,也有一个技巧。在CSAPP中涉及到。那就是`lowbit = x & -x`,因为计算机中,二进制补码就是反码加1.所以原码和补码相与,就能得到最低位的1。知道了最低位,就可以分组,将问题转化为两个`Single Number I`子问题。分组就是将每个数与`lowbit`相与。分组分为低位相同和低位不同。所以这时候分别在分组里异或,就能筛选出要求的两个值了。 41 | 42 | ## Solution 43 | 44 | Python 45 | 46 | ```python 47 | class Solution(object): 48 | def singleNumber(self, nums): 49 | """ 50 | :type nums: List[int] 51 | :rtype: List[int] 52 | """ 53 | nlist = collections.defaultdict(list) 54 | temp = 0 55 | result = [0, 0] 56 | for num in nums: 57 | temp ^= num 58 | mask = temp & -temp 59 | for num in nums: 60 | if num & mask: 61 | result[0] ^= num 62 | else: 63 | result[1] ^= num 64 | return result 65 | ``` 66 | 67 | -------------------------------------------------------------------------------- /136.md: -------------------------------------------------------------------------------- 1 | #136. Single Number 2 | 3 | ## Intro 4 | 5 | Given an array of integers, every element appears twice except for one. Find that single one. 6 | 7 | ### Note 8 | 9 | Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory? 10 | 11 | ## Thinking 12 | 13 | 实话说,看到这道题的时候,我的第一反应时这个答案 14 | 15 | ``` 16 | class Solution(object): 17 | def singleNumber(self, nums): 18 | """ 19 | :type nums: List[int] 20 | :rtype: int 21 | """ 22 | for c in nums: 23 | if nums.count(c) == 1: 24 | print c 25 | break 26 | ``` 27 | 并且第一反应就是肯定会超时,果然不出所料,意料之中的挂了。 28 | 29 | 没办法,只能来想其他的办法。 30 | 31 | 突然想起来回忆中看过一篇关于这道题的介绍,有一个经常被人忽略的技巧,XOR。 32 | 33 | 是的,异或。xor是一个经常被我忽视的操作,可能是对它理解的不够深入,所以不常使用。今天就来研究了一下xor。 34 | 35 | 异或的数学符号为“⊕”,计算机符号为“xor”。其运算法则为: 36 | 37 | ``` 38 | a⊕b = (¬a ∧ b) ∨ (a ∧¬b) 39 | ``` 40 | 41 | 说白了就是两个值相同则为0,不同则为1。计算机中经常使用`^`代表xor操作。 42 | 43 | 假设 a = 3, b = 5, a xor b 就转化为先将a、b转化为二进制 44 | 45 | a 011 46 | 47 | b 101 48 | 49 | 这里都写成3位是为了方便比较。 50 | 51 | 根据之前说到的运算规则,所以 a ^ b = (110)2 = 6 52 | 53 | 此外还可以得到 a ^ a = 0, b ^ b = 0。 54 | 55 | xor的神奇之处就是它具有交换律、结合律。所以 56 | 57 | ``` 58 | a ^ b ^ a = (a ^ a) ^ b = 0 ^ b = b 59 | ``` 60 | 61 | 运用xor,两个数的交换就变得十分神奇(当然这是题外话了): 62 | 63 | ``` 64 | void swap(int a, int b) 65 | 66 | { 67 | a = a ^ b; 68 | b = a ^ b; 69 | a = a ^ b; 70 | } 71 | 72 | ``` 73 | 74 | 回到这道题,从题目条件可以得知除了要找出的那个数只出现了一次,其他数都出现了2次。根据上面的规则,可以发现用xor可以巧妙的让2个相同的数变为0,这样剩那个数就可以很容易得出了。 75 | 76 | ## Solution 77 | 78 | Python 79 | 80 | ```python 81 | class Solution(object): 82 | def singleNumber(self, nums): 83 | """ 84 | :type nums: List[int] 85 | :rtype: int 86 | """ 87 | res = nums[0] 88 | for c in nums[1:]: 89 | res ^= c 90 | return res 91 | ``` 92 | 93 | 再简单一点 94 | 95 | ```python 96 | class Solution(object): 97 | def singleNumber(self, nums): 98 | """ 99 | :type nums: List[int] 100 | :rtype: int 101 | """ 102 | return reduce(lambda x, y: x^y, nums) 103 | ``` 104 | --------------------------------------------------------------------------------