diff --git a/.idea/workspace.xml b/.idea/workspace.xml index a84d8f4..7657e1d 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,7 +2,7 @@ - + @@ -83,7 +83,6 @@ @@ -169,6 +169,7 @@ + @@ -203,7 +204,6 @@ - @@ -545,13 +545,6 @@ - - - - - - - @@ -892,6 +885,14 @@ + + + + + + + + diff --git a/QuickSort.py b/QuickSort.py index cd8a673..59b0972 100644 --- a/QuickSort.py +++ b/QuickSort.py @@ -1,3 +1,5 @@ +# coding: utf-8 + def quickSort(alist): quickSortHelper(alist, 0, len(alist)-1) @@ -16,9 +18,9 @@ def partition(alist, first, last): done = False while not done: - while alist[leftmark] <= pivotvlue and leftmark <= rightmark: + while leftmark <= rightmark and alist[leftmark] <= pivotvlue: # bugfix: 先比较index, 不然数组会越界 leftmark += 1 - while alist[rightmark] >= pivotvlue and rightmark >= leftmark: + while rightmark >= leftmark and alist[rightmark] >= pivotvlue: rightmark -= 1 if leftmark > rightmark: @@ -32,3 +34,13 @@ def partition(alist, first, last): alist2 = [1] quickSort(alist2) print(alist2) + + +if __name__ == "__main__": + test_data = [3,2,111,3,-1,0,0,1,0,2,4] + + res_stable = sorted(test_data) + quickSort(test_data) + print(test_data) + print(res_stable) + assert all(map(lambda x: x[0] == x[1], zip(res_stable, test_data))) \ No newline at end of file diff --git "a/Target Offer/\344\270\215\347\224\250\345\212\240\345\207\217\344\271\230\351\231\244\345\201\232\345\212\240\346\263\225.py" "b/Target Offer/\344\270\215\347\224\250\345\212\240\345\207\217\344\271\230\351\231\244\345\201\232\345\212\240\346\263\225.py" index eef1246..0d8d072 100644 --- "a/Target Offer/\344\270\215\347\224\250\345\212\240\345\207\217\344\271\230\351\231\244\345\201\232\345\212\240\346\263\225.py" +++ "b/Target Offer/\344\270\215\347\224\250\345\212\240\345\207\217\344\271\230\351\231\244\345\201\232\345\212\240\346\263\225.py" @@ -6,13 +6,24 @@ # 可能是python的的整型可以无限大的原因, 导致正数和负数的异或操作不断变成更小的负数而不会溢出 # 使用Swift尝试了一下, 还是可以求得正数和负数的位操作相加运算的 # -*- coding:utf-8 -*- +# class Solution: +# def Add(self, num1, num2): +# while num2: +# sum = num1 ^ num2 +# carry = (num1 & num2) << 1 +# num1 = sum +# num2 = carry +# return num1 +# s = Solution() +# print(s.Add(4, 2)) +# -*- coding:utf-8 -*- +# 通过每次对num1进行与操作保证是一个32位的整形 +# 因此最后我们可以判断符号位是否为1做处理 class Solution: def Add(self, num1, num2): - while num2: - sum = num1 ^ num2 - carry = (num1 & num2) << 1 - num1 = sum - num2 = carry - return num1 -s = Solution() -print(s.Add(4, 2)) + # write code here + while num2 != 0: + temp = num1 ^ num2 + num2 = (num1 & num2) << 1 + num1 = temp & 0xFFFFFFFF + return num1 if num1 >> 31 == 0 else num1 - 4294967296 diff --git "a/Target Offer/\344\272\214\347\273\264\346\225\260\347\273\204\346\237\245\346\211\276.py" "b/Target Offer/\344\272\214\347\273\264\346\225\260\347\273\204\346\237\245\346\211\276.py" index 3d05286..81239fd 100644 --- "a/Target Offer/\344\272\214\347\273\264\346\225\260\347\273\204\346\237\245\346\211\276.py" +++ "b/Target Offer/\344\272\214\347\273\264\346\225\260\347\273\204\346\237\245\346\211\276.py" @@ -29,6 +29,8 @@ def Find(self, array, target): # 判断非法输入 # 可以换成 isinstance(target, (int, float)) 进行判断 if type(target) == float and type(array[0][0]) == int: + if int(target) == target: + return False target = int(target) elif type(target) == int and type(array[0][0]) == float: target = float(int) diff --git "a/Target Offer/\346\233\277\346\215\242\347\251\272\346\240\274.py" "b/Target Offer/\346\233\277\346\215\242\347\251\272\346\240\274.py" index 72e50f2..bd15a41 100644 --- "a/Target Offer/\346\233\277\346\215\242\347\251\272\346\240\274.py" +++ "b/Target Offer/\346\233\277\346\215\242\347\251\272\346\240\274.py" @@ -6,6 +6,20 @@ # -*- coding:utf-8 -*- class Solution: # s 源字符串 + + # 使用append一次遍历即可替换 + # 由于list的append是O(1)的时间复杂度,除了扩容所导致的时间损耗,该算法复杂度为O(n) + def replaceSpaceByAppend(self, s): + string = list(string) + stringReplace = [] + for item in string: + if item == ' ': + stringReplace.append('%') + stringReplace.append('2') + stringReplace.append('0') + else: + stringReplace.append(item) + return "".join(stringReplace) # 创建新的字符串进行替换 def replaceSpace1(self, s): diff --git "a/Target Offer/\351\233\266\351\222\261\346\211\276\351\233\266\344\273\245\345\217\212\350\277\233\351\230\266" "b/Target Offer/\351\233\266\351\222\261\346\211\276\351\233\266\344\273\245\345\217\212\350\277\233\351\230\266" new file mode 100644 index 0000000..0094fd3 --- /dev/null +++ "b/Target Offer/\351\233\266\351\222\261\346\211\276\351\233\266\344\273\245\345\217\212\350\277\233\351\230\266" @@ -0,0 +1,40 @@ +''' +零钱找零问题,使用动态规划 +''' +def ChangeMaking(coinVal, change): + alist = [0]*(change+1) + for i in range(1, change+1): + temp = change; j = 0 + while j <= len(coinVal)-1 and i >= coinVal[j]: + temp = min(alist[i-coinVal[j]], temp) + j += 1 + alist[i] = temp + 1 + return alist.pop() + +print(ChangeMaking([1, 5, 10, 25], 63)) + +''' +零钱找零问题的进阶 +美团笔试题 +给你六中零钱1,5,10,20,50,100的纸币,给定一个金额,写出所有可能的找零的个数 +输入2,输出1;输入5,输出2 +也是使用动态规划 +''' +import sys +try: + while True: + line = sys.stdin.readline().strip() + if line == '': + break + target = int(line) + coinVal = [1, 5, 10, 20, 50, 100] + alist = [0]*(target+1) + alist[0] = 1 + for i in range(6): + j = coinVal[i] + while j <= target: + alist[j] = alist[j] + alist[j-coinVal[i]] + j += 1 + print(alist[-1]) +except: + pass diff --git a/leetcode/143. Reorder List.py b/leetcode/143. Reorder List.py new file mode 100644 index 0000000..838b15c --- /dev/null +++ b/leetcode/143. Reorder List.py @@ -0,0 +1,57 @@ +''' +Given a singly linked list L: L0→L1→…→Ln-1→Ln, +reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… + +You must do this in-place without altering the nodes' values. + +For example, +Given {1,2,3,4}, reorder it to {1,4,2,3}. +''' + + +# Definition for singly-linked list. +class ListNode(object): + def __init__(self, x): + self.val = x + self.next = None + +class Solution(object): + def reorderList(self, head): + if not head or not head.next: + return + ahead, behind = self.split(head) + behind = self.reverse(behind) + head = self.reConnect(ahead, behind) + # split the linkedlist in middle + def split(self, head): + fast = head + slow = head + while fast and fast.next: + slow = slow.next + fast = fast.next + fast = fast.next + middle = slow.next + slow.next = None + return head, middle + # reverse the behind half linkedlist + def reverse(self, head): + reHead = None + curNode = head + while curNode: + nextNode = curNode.next + curNode.next = reHead + reHead = curNode + curNode = nextNode + return reHead + # merge the two linkedlist to one + def reConnect(self, first, second): + head = first + tail = first + first = first.next + while second: + tail.next = second + tail = tail.next + second = second.next + if first: + first, second = second, first + return head \ No newline at end of file diff --git a/leetcode/322. Coin Change b/leetcode/322. Coin Change new file mode 100644 index 0000000..f0eb84e --- /dev/null +++ b/leetcode/322. Coin Change @@ -0,0 +1,41 @@ +''' +You are given coins of different denominations and a total amount of money amount. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1. + +Example 1: +coins = [1, 2, 5], amount = 11 +return 3 (11 = 5 + 5 + 1) + +Example 2: +coins = [2], amount = 3 +return -1. + +Note: +You may assume that you have an infinite number of each kind of coin. +''' +class Solution(object): + def coinChange(self, coins, amount): + #corner cases + if amount == 0: + return 0 + if len(coins) == 1 and coins[0] > amount: + return -1 + dp = [-1 for i in range(amount + 1)] + for i in range(1, amount + 1): + # if the value matches the coin + if i in coins: + dp[i] = 1 + else: + minV = sys.maxsize + # since the size of coins are much less than the amount, + # we check if for every coin there could be a solution and find the minimum of that + for j in coins: + remain = i - j + # -1 means there is no solution, so we don't need to check if dp[i] is -1 + if remain > 0 and dp[remain] != -1: + minV = min(minV, dp[remain]) + if minV ==sys.maxsize: + dp[i] = -1 + else: + dp[i] = minV + 1 + return dp[-1] + diff --git a/leetcode/337. House Robber III b/leetcode/337. House Robber III new file mode 100644 index 0000000..c5cd083 --- /dev/null +++ b/leetcode/337. House Robber III @@ -0,0 +1,44 @@ +''' +The thief has found himself a new place for his thievery again. There is only one entrance to this area, called the "root." Besides the root, each house has one and only one parent house. After a tour, the smart thief realized that "all houses in this place forms a binary tree". It will automatically contact the police if two directly-linked houses were broken into on the same night. + +Determine the maximum amount of money the thief can rob tonight without alerting the police. + +Example 1: + 3 + / \ + 2 3 + \ \ + 3 1 +Maximum amount of money the thief can rob = 3 + 3 + 1 = 7. +Example 2: + 3 + / \ + 4 5 + / \ \ + 1 3 1 +Maximum amount of money the thief can rob = 4 + 5 = 9. +''' +# Definition for a binary tree node. +# class TreeNode(object): +# def __init__(self, x): +# self.val = x +# self.left = None +# self.right = None + +class Solution(object): + def rob(self, root): + def gain(root): + if root == None: + return 0 + o1 = root.val + if o1 < 0: + return -o1 + if root.left: + o1 += gain(root.left.left) + gain(root.left.right) + if root.right: + o1 += gain(root.right.left) + gain(root.right.right) + o2 = gain(root.left) + gain(root.right) + o = max(o1,o2) + root.val = -1*o + return o + return gain(root) diff --git a/leetcode/4. Median of Two Sorted Arrays b/leetcode/4. Median of Two Sorted Arrays new file mode 100644 index 0000000..0c74b39 --- /dev/null +++ b/leetcode/4. Median of Two Sorted Arrays @@ -0,0 +1,49 @@ +''' +There are two sorted arrays nums1 and nums2 of size m and n respectively. + +Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). + +Example 1: +nums1 = [1, 3] +nums2 = [2] + +The median is 2.0 +Example 2: +nums1 = [1, 2] +nums2 = [3, 4] + +The median is (2 + 3)/2 = 2.5 +''' +class Solution(object): + def findMedianSortedArrays(self, a, b): + n = len(a)+len(b) + if n&1: + return self.kthSmallest(a,b,n//2+1) + else: + return (self.kthSmallest(a,b,n//2+1) + self.kthSmallest(a,b,n//2))/2.0 + + def kthSmallest(self,a,b,k): + if len(a)+len(b) < k: + return None + i=0 + j=0 + flag = True + while k>0: + if i >= len(a): + j+=1 + flag = False + elif j >= len(b): + i+=1 + flag = True + elif a[i] <= b[j]: + i+=1 + flag = True + elif a[i] > b[j]: + j+=1 + flag = False + k-=1 + + if flag: + return a[i-1] + else: + return b[j-1] diff --git a/leetcode/7. Reverse Integer QuestionEditorial Solution b/leetcode/7. Reverse Integer QuestionEditorial Solution new file mode 100644 index 0000000..acc9d2d --- /dev/null +++ b/leetcode/7. Reverse Integer QuestionEditorial Solution @@ -0,0 +1,35 @@ +''' +Reverse digits of an integer. + +Example1: x = 123, return 321 +Example2: x = -123, return -321 + +''' + +class Solution(object): + def reverse(self, x): + res = int(str(abs(x))[::-1]) + if x < 0: + res = -res + if res > 2147483647 or res < -2147483648: + res = 0 + return res + # without str() + def reverse2(self, x): from math import log + if x < 10 and x > -10: + return x + flipped = False + if x < 0: + flipped = True + x *= -1 + res = 0 + log10 = int(log(x, 10)) + for i in xrange(log10 + 1): + digit = x % 10 + res += digit * 10**(log10 - i) + x /= 10 + if res > 2**31 - 1 or res < -1 * 2**31 + 1: + return 0 + if flipped: + res *= -1 + return res