├── python ├── Leetcode │ └── code440.py ├── CodingInterviews │ ├── README.md │ ├── offer05.py │ ├── offer17.py │ ├── offer39.py │ ├── offer15.py │ ├── offer03.py │ ├── offer11.py │ ├── offer42.py │ ├── offer10I.py │ ├── offer46.py │ ├── offer50.py │ ├── offer51.py │ ├── offer10II.py │ ├── offer16.py │ ├── offer06.py │ ├── offer63.py │ ├── offer14II.py │ ├── offer19.py │ ├── offer49.py │ ├── offer09.py │ ├── offer48.py │ ├── offer22.py │ ├── offer31.py │ ├── offer33.py │ ├── offer44.py │ ├── offer04.py │ ├── offer43.py │ ├── offer24.py │ ├── offer27.py │ ├── offer25.py │ ├── offer30.py │ ├── offer21.py │ ├── offer18.py │ ├── offer38.py │ ├── offer41.py │ ├── offer32I.py │ ├── offer07.py │ ├── offer26.py │ ├── offer47.py │ ├── offer28.py │ ├── offer14I.py │ ├── offer40.py │ ├── offer13.py │ ├── offer12.py │ ├── offer35.py │ ├── offer45.py │ ├── offer32II.py │ ├── offer34.py │ ├── offer36.py │ ├── offer32III.py │ ├── offer29.py │ ├── offer20.py │ └── offer37.py └── SortingAlgorithm │ ├── BubbleSort.py │ ├── SelectionSort.py │ ├── InsertionSort.py │ ├── RadixSort.py │ ├── ShellSort.py │ ├── BucketSort.py │ ├── CountingSort.py │ ├── QuickSort.py │ ├── MergeSort.py │ └── HeapSort.py ├── .gitignore ├── README.md └── LICENSE /python/Leetcode/code440.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 字典序的第K小数字 4 | Author: 5 | Charles 6 | ''' 7 | -------------------------------------------------------------------------------- /python/CodingInterviews/README.md: -------------------------------------------------------------------------------- 1 | # Explanation 2 | ``` 3 | The OJ used is https://leetcode-cn.com/problemset/lcof/ 4 | ``` -------------------------------------------------------------------------------- /python/CodingInterviews/offer05.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 替换空格 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def replaceSpace(self, s: str) -> str: 9 | return s.replace(' ', '%20') -------------------------------------------------------------------------------- /python/CodingInterviews/offer17.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 打印从1到最大的n位数 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def printNumbers(self, n: int) -> List[int]: 9 | start, end = 1, 10 ** n 10 | return list(range(start, end)) -------------------------------------------------------------------------------- /python/CodingInterviews/offer39.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 数组中出现次数超过一半的数字 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def majorityElement(self, nums: List[int]) -> int: 9 | nums.sort() 10 | mid = int(len(nums) / 2) 11 | return nums[mid] -------------------------------------------------------------------------------- /python/CodingInterviews/offer15.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 二进制中1的个数 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def hammingWeight(self, n: int) -> int: 9 | count = 0 10 | while n: 11 | n &= n - 1 12 | count += 1 13 | return count -------------------------------------------------------------------------------- /python/CodingInterviews/offer03.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 数组中重复的数字 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def findRepeatNumber(self, nums: List[int]) -> int: 9 | nums.sort() 10 | for i in range(len(nums)-1): 11 | if nums[i] == nums[i+1]: 12 | return nums[i] -------------------------------------------------------------------------------- /python/CodingInterviews/offer11.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 旋转数组的最小数字 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def minArray(self, numbers: List[int]) -> int: 9 | for i in range(len(numbers)-1): 10 | if numbers[i] > numbers[i+1]: 11 | return numbers[i+1] 12 | return numbers[0] -------------------------------------------------------------------------------- /python/CodingInterviews/offer42.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 连续子数组的最大和 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def maxSubArray(self, nums: List[int]) -> int: 9 | if not nums: return 0 10 | for i in range(1, len(nums)): 11 | nums[i] = max(nums[i], nums[i]+nums[i-1]) 12 | return max(nums) -------------------------------------------------------------------------------- /python/CodingInterviews/offer10I.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 斐波那契数列 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | memory = {} 9 | def fib(self, n: int) -> int: 10 | if n <= 1: return n 11 | if n not in self.memory: 12 | self.memory[n] = (self.fib(n-1) + self.fib(n-2)) % 1000000007 13 | return self.memory[n] -------------------------------------------------------------------------------- /python/CodingInterviews/offer46.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 把数字翻译成字符串 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def translateNum(self, num: int) -> int: 9 | num = str(num) 10 | a, b = 1, 1 11 | for i in range(2, len(num)+1): 12 | a, b = (a + b if '10' <= num[i-2: i] <= '25' else a), a 13 | return a -------------------------------------------------------------------------------- /python/CodingInterviews/offer50.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 第一个只出现一次的字符 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def firstUniqChar(self, s: str) -> str: 9 | count = {} 10 | for c in s: 11 | count[c] = c not in count 12 | for key, value in count.items(): 13 | if value: return key 14 | return ' ' -------------------------------------------------------------------------------- /python/CodingInterviews/offer51.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 数组中的逆序对 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def firstUniqChar(self, s: str) -> str: 9 | count = {} 10 | for c in s: 11 | count[c] = c not in count 12 | for key, value in count.items(): 13 | if value: return key 14 | return ' ' -------------------------------------------------------------------------------- /python/CodingInterviews/offer10II.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 青蛙跳台阶问题 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | memory = {} 9 | def numWays(self, n: int) -> int: 10 | if n <= 1: return 1 11 | if n not in self.memory: 12 | self.memory[n] = (self.numWays(n-1) + self.numWays(n-2)) % 1000000007 13 | return self.memory[n] -------------------------------------------------------------------------------- /python/CodingInterviews/offer16.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 数值的整数次方 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def myPow(self, x: float, n: int) -> float: 9 | if n < 0: 10 | x, n = 1./x, -n 11 | res = 1 12 | while n: 13 | if n & 1: res *= x 14 | x *= x 15 | n >>= 1 16 | return res -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | -------------------------------------------------------------------------------- /python/CodingInterviews/offer06.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 从尾到头打印链表 4 | Author: 5 | Charles 6 | ''' 7 | # Definition for singly-linked list. 8 | # class ListNode: 9 | # def __init__(self, x): 10 | # self.val = x 11 | # self.next = None 12 | 13 | class Solution: 14 | def reversePrint(self, head: ListNode) -> List[int]: 15 | if not head: return [] 16 | return self.reversePrint(head.next) + [head.val] -------------------------------------------------------------------------------- /python/CodingInterviews/offer63.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 股票的最大利润 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def maxProfit(self, prices: List[int]) -> int: 9 | if not prices: return 0 10 | dp = [0,] * len(prices) 11 | min_ = prices[0] 12 | for i in range(1, len(prices)): 13 | dp[i] = max(dp[i-1], prices[i] - min_) 14 | if min_ > prices[i]: min_ = prices[i] 15 | return dp[-1] -------------------------------------------------------------------------------- /python/CodingInterviews/offer14II.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 剪绳子 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def cuttingRope(self, n: int) -> int: 9 | if n <= 3: return n - 1 10 | nums = [] 11 | while n >= 3: 12 | n -= 3 13 | nums.append(3) 14 | if n == 2: nums.append(2) 15 | else: nums.append(n+nums.pop()) 16 | res = 1 17 | for n in nums: res *= n 18 | return res % 1000000007 -------------------------------------------------------------------------------- /python/CodingInterviews/offer19.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 正则表达式匹配 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def isMatch(self, s: str, p: str) -> bool: 9 | if not p: return not s 10 | first_match = bool(s and p[0] in (s[0], '.')) 11 | if len(p) > 1 and p[1] == '*': 12 | return self.isMatch(s, p[2:]) or (first_match and self.isMatch(s[1:], p)) 13 | else: 14 | return first_match and self.isMatch(s[1:], p[1:]) -------------------------------------------------------------------------------- /python/CodingInterviews/offer49.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 丑数 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def nthUglyNumber(self, n: int) -> int: 9 | dp, a, b, c = [1,] * n, 0, 0, 0 10 | for i in range(1, n): 11 | n1, n2, n3 = dp[a] * 2, dp[b] * 3, dp[c] * 5 12 | dp[i] = min([n1, n2, n3]) 13 | if dp[i] == n1: a += 1 14 | if dp[i] == n2: b += 1 15 | if dp[i] == n3: c += 1 16 | return dp[-1] -------------------------------------------------------------------------------- /python/CodingInterviews/offer09.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 用两个栈实现队列 4 | Author: 5 | Charles 6 | ''' 7 | class CQueue: 8 | def __init__(self): 9 | self.A = [] 10 | self.B = [] 11 | def appendTail(self, value: int) -> None: 12 | self.A.append(value) 13 | def deleteHead(self) -> int: 14 | if self.B: return self.B.pop() 15 | if not self.A: return -1 16 | while self.A: 17 | self.B.append(self.A.pop()) 18 | return self.B.pop() -------------------------------------------------------------------------------- /python/CodingInterviews/offer48.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 最长不含重复字符的子字符串 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def lengthOfLongestSubstring(self, s: str) -> int: 9 | if not s: return 0 10 | dp = [1,] * len(s) 11 | for i in range(1, len(s)): 12 | if s[i] not in s[i-dp[i-1]: i]: 13 | dp[i] = dp[i] + dp[i-1] 14 | else: 15 | idx = s[i-dp[i-1]: i].index(s[i]) 16 | dp[i] = dp[i-1] - idx 17 | return max(dp) -------------------------------------------------------------------------------- /python/CodingInterviews/offer22.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 链表中倒数第k个节点 4 | Author: 5 | Charles 6 | ''' 7 | # Definition for singly-linked list. 8 | # class ListNode: 9 | # def __init__(self, x): 10 | # self.val = x 11 | # self.next = None 12 | 13 | class Solution: 14 | def getKthFromEnd(self, head: ListNode, k: int) -> ListNode: 15 | n0, n1 = head, head 16 | for i in range(k): n1 = n1.next 17 | while n1: 18 | n0 = n0.next 19 | n1 = n1.next 20 | return n0 -------------------------------------------------------------------------------- /python/CodingInterviews/offer31.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 栈的压入、弹出序列 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def validateStackSequences(self, pushed: List[int], popped: List[int]) -> bool: 9 | stack = [] 10 | while True: 11 | if not pushed: 12 | break 13 | stack.append(pushed.pop(0)) 14 | while stack and (popped[0] == stack[-1]): 15 | popped.pop(0) 16 | stack.pop() 17 | return True if not stack else False -------------------------------------------------------------------------------- /python/CodingInterviews/offer33.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 二叉搜索树的后序遍历序列 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def verifyPostorder(self, postorder: List[int]) -> bool: 9 | def recur(i, j): 10 | if i > j: return True 11 | p = i 12 | while postorder[p] < postorder[j]: p += 1 13 | left = p 14 | while postorder[p] > postorder[j]: p += 1 15 | return p == j and recur(i, left-1) and recur(left, j-1) 16 | return recur(0, len(postorder)-1) -------------------------------------------------------------------------------- /python/CodingInterviews/offer44.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 数字序列中某一位的数字 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def findNthDigit(self, n: int) -> int: 9 | num_digitals, start, end = 1, 0, 10 10 | while True: 11 | length = (end - start) * num_digitals 12 | if n - length < 0: 13 | break 14 | n = n - length 15 | start, end, num_digitals = end, end * 10, num_digitals + 1 16 | digital = start + n // num_digitals 17 | return int(str(digital)[n % num_digitals]) -------------------------------------------------------------------------------- /python/CodingInterviews/offer04.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 二维数组中的查找 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool: 9 | if not matrix: return False 10 | num_rows, num_cols = len(matrix), len(matrix[0]) 11 | row, col = num_rows - 1, 0 12 | while row >= 0 and col < num_cols: 13 | num = matrix[row][col] 14 | if num == target: return True 15 | elif num > target: row -= 1 16 | else: col += 1 17 | return False -------------------------------------------------------------------------------- /python/CodingInterviews/offer43.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 1~n整数中1出现的次数 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def countDigitOne(self, n: int) -> int: 9 | digital, count = 1, 0 10 | high, cur, low = n // 10, n % 10, 0 11 | while high != 0 or cur != 0: 12 | if cur == 0: count += high * digital 13 | elif cur == 1: count += high * digital + low + 1 14 | else: count += (high + 1) * digital 15 | low, cur, high = cur * digital + low, high % 10, high // 10 16 | digital *= 10 17 | return count -------------------------------------------------------------------------------- /python/CodingInterviews/offer24.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 反转链表 4 | Author: 5 | Charles 6 | ''' 7 | # Definition for singly-linked list. 8 | # class ListNode: 9 | # def __init__(self, x): 10 | # self.val = x 11 | # self.next = None 12 | 13 | class Solution: 14 | def reverseList(self, head: ListNode) -> ListNode: 15 | def recur(prev, head): 16 | if not head: return prev 17 | next = head.next 18 | head.next = prev 19 | head, prev = next, head 20 | return recur(prev, head) 21 | return recur(None, head) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # algorithm 2 | ```sh 3 | algorithm practice using c/c++/python. 4 | ``` 5 | 6 | # Contents 7 | | Name | Python | C++ | C | In Chinese | 8 | | :----: | :----: | :----: | :----: | :----: | 9 | | Sorting Algorithm | ✓ | ✗ | ✗ | 十大经典排序算法 | 10 | | Coding Interviews | ✓ | ✗ | ✗ | 剑指Offer(第二版) | 11 | | Leetcode | ✗ | ✗ | ✗ | Leetcode算法题 | -------------------------------------------------------------------------------- /python/CodingInterviews/offer27.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 二叉树的镜像 4 | Author: 5 | Charles 6 | ''' 7 | # Definition for a binary tree node. 8 | # class TreeNode: 9 | # def __init__(self, x): 10 | # self.val = x 11 | # self.left = None 12 | # self.right = None 13 | 14 | class Solution: 15 | def mirrorTree(self, root: TreeNode) -> TreeNode: 16 | def recur(root): 17 | if not root: return 18 | root.left, root.right = root.right, root.left 19 | recur(root.left) 20 | recur(root.right) 21 | recur(root) 22 | return root -------------------------------------------------------------------------------- /python/CodingInterviews/offer25.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 合并两个排序的链表 4 | Author: 5 | Charles 6 | ''' 7 | # Definition for singly-linked list. 8 | # class ListNode: 9 | # def __init__(self, x): 10 | # self.val = x 11 | # self.next = None 12 | 13 | class Solution: 14 | def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode: 15 | if not l1: return l2 16 | if not l2: return l1 17 | if l1.val < l2.val: 18 | l1.next = self.mergeTwoLists(l1.next, l2) 19 | return l1 20 | else: 21 | l2.next = self.mergeTwoLists(l1, l2.next) 22 | return l2 -------------------------------------------------------------------------------- /python/CodingInterviews/offer30.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 包含min函数的栈 4 | Author: 5 | Charles 6 | ''' 7 | class MinStack: 8 | def __init__(self): 9 | self.A = [] 10 | self.B = [] 11 | def push(self, x: int) -> None: 12 | self.A.append(x) 13 | if not self.B: 14 | self.B.append(x) 15 | else: 16 | if self.B[-1] >= x: self.B.append(x) 17 | def pop(self) -> None: 18 | if self.A: n = self.A.pop() 19 | if n == self.B[-1]: self.B.pop() 20 | def top(self) -> int: 21 | return self.A[-1] 22 | def min(self) -> int: 23 | return self.B[-1] -------------------------------------------------------------------------------- /python/CodingInterviews/offer21.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 调整数组顺序使奇数位于偶数前面 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def exchange(self, nums: List[int]) -> List[int]: 9 | p0, p1 = 0, len(nums) - 1 10 | while p0 < p1: 11 | if nums[p0] % 2 == 0 and nums[p1] % 2: 12 | nums[p0], nums[p1] = nums[p1], nums[p0] 13 | p0 += 1 14 | p1 -= 1 15 | elif nums[p0] % 2 == 0: 16 | p1 -= 1 17 | elif nums[p1] % 2: 18 | p0 += 1 19 | else: 20 | p0 += 1 21 | p1 -= 1 22 | return nums -------------------------------------------------------------------------------- /python/CodingInterviews/offer18.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 删除链表的节点 4 | Author: 5 | Charles 6 | ''' 7 | # Definition for singly-linked list. 8 | # class ListNode: 9 | # def __init__(self, x): 10 | # self.val = x 11 | # self.next = None 12 | 13 | class Solution: 14 | def deleteNode(self, head: ListNode, val: int) -> ListNode: 15 | if not head: return head 16 | if head.val == val: return head.next 17 | pre, now = head, head.next 18 | while now: 19 | if now.val == val: 20 | pre.next = now.next 21 | break 22 | pre, now = now, now.next 23 | return head -------------------------------------------------------------------------------- /python/CodingInterviews/offer38.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 字符串的排列 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def permutation(self, s: str) -> List[str]: 9 | res, s = [], list(s) 10 | def dfs(boundary): 11 | if boundary == len(s) - 1: return res.append(''.join(s)) 12 | dic = set() 13 | for i in range(boundary, len(s)): 14 | if s[i] in dic: continue 15 | dic.add(s[i]) 16 | s[i], s[boundary] = s[boundary], s[i] 17 | dfs(boundary+1) 18 | s[i], s[boundary] = s[boundary], s[i] 19 | dfs(0) 20 | return list(res) -------------------------------------------------------------------------------- /python/CodingInterviews/offer41.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 数据流中的中位数 4 | Author: 5 | Charles 6 | ''' 7 | from heapq import * 8 | 9 | class MedianFinder: 10 | def __init__(self): 11 | self.A, self.B = [], [] 12 | def addNum(self, num: int) -> None: 13 | if len(self.A) != len(self.B): 14 | heappush(self.A, num) 15 | heappush(self.B, -heappop(self.A)) 16 | else: 17 | heappush(self.B, -num) 18 | heappush(self.A, -heappop(self.B)) 19 | def findMedian(self) -> float: 20 | if not self.A: return [] 21 | return self.A[0] if len(self.A) != len(self.B) else (self.A[0] - self.B[0]) / 2.0 -------------------------------------------------------------------------------- /python/CodingInterviews/offer32I.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 从上到下打印二叉树 4 | Author: 5 | Charles 6 | ''' 7 | # Definition for a binary tree node. 8 | # class TreeNode: 9 | # def __init__(self, x): 10 | # self.val = x 11 | # self.left = None 12 | # self.right = None 13 | 14 | class Solution: 15 | def levelOrder(self, root: TreeNode) -> List[int]: 16 | if not root: return [] 17 | res, queue = [], [root] 18 | while queue: 19 | node = queue.pop(0) 20 | res.append(node.val) 21 | if node.left: queue.append(node.left) 22 | if node.right: queue.append(node.right) 23 | return res -------------------------------------------------------------------------------- /python/CodingInterviews/offer07.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 重建二叉树 4 | Author: 5 | Charles 6 | ''' 7 | # Definition for a binary tree node. 8 | # class TreeNode: 9 | # def __init__(self, x): 10 | # self.val = x 11 | # self.left = None 12 | # self.right = None 13 | 14 | class Solution: 15 | def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode: 16 | if not inorder: return None 17 | root = TreeNode(preorder[0]) 18 | idx = inorder.index(preorder[0]) 19 | root.left = self.buildTree(preorder[1: idx+1], inorder[:idx]) 20 | root.right = self.buildTree(preorder[idx+1:], inorder[idx+1:]) 21 | return root -------------------------------------------------------------------------------- /python/CodingInterviews/offer26.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 树的子结构 4 | Author: 5 | Charles 6 | ''' 7 | # Definition for a binary tree node. 8 | # class TreeNode: 9 | # def __init__(self, x): 10 | # self.val = x 11 | # self.left = None 12 | # self.right = None 13 | 14 | class Solution: 15 | def isSubStructure(self, A: TreeNode, B: TreeNode) -> bool: 16 | def recur(A, B): 17 | if not B: return True 18 | if not A or A.val != B.val: return False 19 | return recur(A.left, B.left) and recur(A.right, B.right) 20 | return bool(A and B) and (recur(A, B) or self.isSubStructure(A.left, B) or self.isSubStructure(A.right, B)) -------------------------------------------------------------------------------- /python/CodingInterviews/offer47.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 礼物的最大价值 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def maxValue(self, grid: List[List[int]]) -> int: 9 | num_rows, num_cols = len(grid), len(grid[0]) 10 | dp = [[0,] * num_cols for _ in range(num_rows)] 11 | for i in range(num_rows): 12 | for j in range(num_cols): 13 | if i == 0 and j == 0: dp[i][j] = grid[i][j] 14 | elif i == 0: dp[i][j] = dp[i][j-1] + grid[i][j] 15 | elif j == 0: dp[i][j] = dp[i-1][j] + grid[i][j] 16 | else: dp[i][j] = max(dp[i][j-1] + grid[i][j], dp[i-1][j] + grid[i][j]) 17 | return dp[-1][-1] -------------------------------------------------------------------------------- /python/SortingAlgorithm/BubbleSort.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 冒泡排序 4 | Author: 5 | Charles 6 | 微信公众号: 7 | Charles的皮卡丘 8 | ''' 9 | import random 10 | 11 | 12 | '''冒泡排序''' 13 | def BubbleSort(array): 14 | length = len(array) 15 | for i in range(length): 16 | for j in range(length-i-1): 17 | if array[j] > array[j+1]: array[j+1], array[j] = array[j], array[j+1] 18 | return array 19 | 20 | 21 | '''test''' 22 | if __name__ == '__main__': 23 | array = [random.randint(0, 100) for _ in range(10)] 24 | array_sort = BubbleSort(array.copy()) 25 | print('INPUT:\n%s' % ','.join([str(i) for i in array])) 26 | print('OUTPUT:\n%s' % ','.join([str(i) for i in array_sort])) -------------------------------------------------------------------------------- /python/CodingInterviews/offer28.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 对称的二叉树 4 | Author: 5 | Charles 6 | ''' 7 | # Definition for a binary tree node. 8 | # class TreeNode: 9 | # def __init__(self, x): 10 | # self.val = x 11 | # self.left = None 12 | # self.right = None 13 | 14 | class Solution: 15 | def isSymmetric(self, root: TreeNode) -> bool: 16 | if not root: return True 17 | def recur(left, right): 18 | if not left: return not right 19 | if not right: return not left 20 | if left.val != right.val: return False 21 | return recur(left.left, right.right) and recur(left.right, right.left) 22 | return recur(root.left, root.right) -------------------------------------------------------------------------------- /python/CodingInterviews/offer14I.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 剪绳子 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def cuttingRope(self, n: int) -> int: 9 | if n <= 3: return n - 1 10 | nums = [] 11 | while n >= 3: 12 | n -= 3 13 | nums.append(3) 14 | if n == 2: nums.append(2) 15 | else: nums.append(n+nums.pop()) 16 | res = 1 17 | for n in nums: res *= n 18 | return res 19 | 20 | 21 | class Solution: 22 | def cuttingRope(self, n: int) -> int: 23 | dp = [1,] * (n + 1) 24 | for i in range(2, n+1): 25 | for j in range(1, i): 26 | dp[i] = max(dp[i], max(j, dp[j]) * max(i-j, dp[i-j])) 27 | return dp[-1] -------------------------------------------------------------------------------- /python/CodingInterviews/offer40.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 最小的k个数 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def getLeastNumbers(self, arr: List[int], k: int) -> List[int]: 9 | def QuickSort(arr, left, right): 10 | if left >= right: return 11 | i, j, partition = left, right, arr[left] 12 | while i < j: 13 | while i < j and arr[j] >= partition: j -= 1 14 | arr[i] = arr[j] 15 | while i < j and arr[i] <= partition: i += 1 16 | arr[j] = arr[i] 17 | arr[i] = partition 18 | QuickSort(arr, left, i-1) 19 | QuickSort(arr, i+1, right) 20 | QuickSort(arr, 0, len(arr)-1) 21 | return arr[:k] -------------------------------------------------------------------------------- /python/CodingInterviews/offer13.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 机器人的运动范围 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def movingCount(self, m: int, n: int, k: int) -> int: 9 | def isvalid(x, y): 10 | s = 0 11 | for i in str(x)+str(y): s += int(i) 12 | return s <= k 13 | flags = [[0,] * n for _ in range(m)] 14 | def dfs(x, y): 15 | if x < 0 or x >= m or y < 0 or y >= n: return 16 | if (not isvalid(x, y)) or flags[x][y]: return 17 | flags[x][y] = 1 18 | dfs(x+1, y) 19 | dfs(x, y+1) 20 | dfs(x-1, y) 21 | dfs(x, y-1) 22 | dfs(0, 0) 23 | count = sum([sum(each) for each in flags]) 24 | return count -------------------------------------------------------------------------------- /python/CodingInterviews/offer12.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 矩阵中的路径 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def exist(self, board: List[List[str]], word: str) -> bool: 9 | def dfs(i, j, k): 10 | if i < 0 or i >= len(board) or j < 0 or j >= len(board[0]): return False 11 | if board[i][j] != word[k]: return False 12 | if k == len(word) - 1: return True 13 | tmp, board[i][j] = board[i][j], '/' 14 | res = dfs(i+1, j, k+1) or dfs(i-1, j, k+1) or dfs(i, j-1, k+1) or dfs(i, j+1, k+1) 15 | board[i][j] = tmp 16 | return res 17 | for i in range(len(board)): 18 | for j in range(len(board[0])): 19 | if dfs(i, j, 0): return True 20 | return False -------------------------------------------------------------------------------- /python/SortingAlgorithm/SelectionSort.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 选择排序 4 | Author: 5 | Charles 6 | 微信公众号: 7 | Charles的皮卡丘 8 | ''' 9 | import random 10 | 11 | 12 | '''选择排序''' 13 | def SelectionSort(array): 14 | length = len(array) 15 | for i in range(length-1): 16 | idx_min = i 17 | for j in range(i+1, length): 18 | if array[j] < array[idx_min]: 19 | idx_min = j 20 | array[i], array[idx_min] = array[idx_min], array[i] 21 | return array 22 | 23 | 24 | '''test''' 25 | if __name__ == '__main__': 26 | array = [random.randint(0, 100) for _ in range(10)] 27 | array_sort = SelectionSort(array.copy()) 28 | print('INPUT:\n%s' % ','.join([str(i) for i in array])) 29 | print('OUTPUT:\n%s' % ','.join([str(i) for i in array_sort])) -------------------------------------------------------------------------------- /python/CodingInterviews/offer35.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 复杂链表的复制 4 | Author: 5 | Charles 6 | ''' 7 | """ 8 | # Definition for a Node. 9 | class Node: 10 | def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None): 11 | self.val = int(x) 12 | self.next = next 13 | self.random = random 14 | """ 15 | 16 | class Solution: 17 | def copyRandomList(self, head: 'Node') -> 'Node': 18 | record = {} 19 | def dfs(head): 20 | if not head: return 21 | if head in record: 22 | return record[head] 23 | copy = Node(head.val) 24 | record[head] = copy 25 | copy.next = dfs(head.next) 26 | copy.random = dfs(head.random) 27 | return copy 28 | return dfs(head) -------------------------------------------------------------------------------- /python/SortingAlgorithm/InsertionSort.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 插入排序 4 | Author: 5 | Charles 6 | 微信公众号: 7 | Charles的皮卡丘 8 | ''' 9 | import random 10 | 11 | 12 | '''插入排序''' 13 | def InsertionSort(array): 14 | length = len(array) 15 | for i in range(1, length): 16 | pointer, cur = i - 1, array[i] 17 | while pointer >= 0 and array[pointer] > cur: 18 | array[pointer+1] = array[pointer] 19 | pointer -= 1 20 | array[pointer+1] = cur 21 | return array 22 | 23 | 24 | '''test''' 25 | if __name__ == '__main__': 26 | array = [random.randint(0, 100) for _ in range(10)] 27 | array_sort = InsertionSort(array.copy()) 28 | print('INPUT:\n%s' % ','.join([str(i) for i in array])) 29 | print('OUTPUT:\n%s' % ','.join([str(i) for i in array_sort])) -------------------------------------------------------------------------------- /python/SortingAlgorithm/RadixSort.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 基数排序 4 | Author: 5 | Charles 6 | 微信公众号: 7 | Charles的皮卡丘 8 | ''' 9 | import random 10 | 11 | 12 | '''基数排序(假设都是整数)''' 13 | def RadixSort(array): 14 | max_value = max(array) 15 | num_digits = len(str(max_value)) 16 | for i in range(num_digits): 17 | buckets = [[] for k in range(10)] 18 | for j in array: 19 | buckets[int(j / (10 ** i)) % 10].append(j) 20 | array = [m for bucket in buckets for m in bucket] 21 | return array 22 | 23 | 24 | '''test''' 25 | if __name__ == '__main__': 26 | array = [random.randint(0, 100) for _ in range(10)] 27 | array_sort = RadixSort(array.copy()) 28 | print('INPUT:\n%s' % ','.join([str(i) for i in array])) 29 | print('OUTPUT:\n%s' % ','.join([str(i) for i in array_sort])) -------------------------------------------------------------------------------- /python/CodingInterviews/offer45.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 把数组排成最小的数 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def minNumber(self, nums: List[int]) -> str: 9 | nums = [str(i) for i in nums] 10 | def QuickSort(nums, left, right): 11 | if left >= right: return 12 | partition, i, j = nums[left], left, right 13 | while i < j: 14 | while i < j and nums[j] + partition >= partition + nums[j]: j -= 1 15 | nums[i] = nums[j] 16 | while i < j and nums[i] + partition <= partition + nums[i]: i += 1 17 | nums[j] = nums[i] 18 | nums[i] = partition 19 | QuickSort(nums, left, i-1) 20 | QuickSort(nums, i+1, right) 21 | QuickSort(nums, 0, len(nums)-1) 22 | return ''.join(nums) -------------------------------------------------------------------------------- /python/CodingInterviews/offer32II.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 从上到下打印二叉树 II 4 | Author: 5 | Charles 6 | ''' 7 | # Definition for a binary tree node. 8 | # class TreeNode: 9 | # def __init__(self, x): 10 | # self.val = x 11 | # self.left = None 12 | # self.right = None 13 | 14 | class Solution: 15 | def levelOrder(self, root: TreeNode) -> List[List[int]]: 16 | if not root: return [] 17 | res, queue = [], [[root]] 18 | while queue: 19 | nodes, res_lvl, next_lvl = queue.pop(0), [], [] 20 | for node in nodes: 21 | res_lvl.append(node.val) 22 | if node.left: next_lvl.append(node.left) 23 | if node.right: next_lvl.append(node.right) 24 | if next_lvl: queue.append(next_lvl) 25 | if res_lvl: res.append(res_lvl) 26 | return res -------------------------------------------------------------------------------- /python/SortingAlgorithm/ShellSort.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 希尔排序 4 | Author: 5 | Charles 6 | 微信公众号: 7 | Charles的皮卡丘 8 | ''' 9 | import random 10 | 11 | 12 | '''希尔排序''' 13 | def ShellSort(array): 14 | length = len(array) 15 | gap = length // 2 16 | while gap > 0: 17 | for i in range(gap, length): 18 | j, cur = i, array[i] 19 | while (j - gap >= 0) and (cur < array[j - gap]): 20 | array[j] = array[j - gap] 21 | j = j - gap 22 | array[j] = cur 23 | gap = gap // 2 24 | return array 25 | 26 | 27 | '''test''' 28 | if __name__ == '__main__': 29 | array = [random.randint(0, 100) for _ in range(10)] 30 | array_sort = ShellSort(array.copy()) 31 | print('INPUT:\n%s' % ','.join([str(i) for i in array])) 32 | print('OUTPUT:\n%s' % ','.join([str(i) for i in array_sort])) -------------------------------------------------------------------------------- /python/SortingAlgorithm/BucketSort.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 桶排序 4 | Author: 5 | Charles 6 | 微信公众号: 7 | Charles的皮卡丘 8 | ''' 9 | import random 10 | 11 | 12 | '''桶排序(假设都是整数)''' 13 | def BucketSort(array): 14 | max_value, min_value, length = max(array), min(array), len(array) 15 | buckets = [0 for _ in range(min_value, max_value+1)] 16 | for i in range(length): 17 | buckets[array[i]-min_value] += 1 18 | output = [] 19 | for i in range(len(buckets)): 20 | if buckets[i] != 0: 21 | output += [i+min_value] * buckets[i] 22 | return output 23 | 24 | 25 | '''test''' 26 | if __name__ == '__main__': 27 | array = [random.randint(0, 100) for _ in range(10)] 28 | array_sort = BucketSort(array.copy()) 29 | print('INPUT:\n%s' % ','.join([str(i) for i in array])) 30 | print('OUTPUT:\n%s' % ','.join([str(i) for i in array_sort])) -------------------------------------------------------------------------------- /python/CodingInterviews/offer34.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 二叉树中和为某一值的路径 4 | Author: 5 | Charles 6 | ''' 7 | # Definition for a binary tree node. 8 | # class TreeNode: 9 | # def __init__(self, x): 10 | # self.val = x 11 | # self.left = None 12 | # self.right = None 13 | 14 | class Solution: 15 | def pathSum(self, root: TreeNode, sum: int) -> List[List[int]]: 16 | paths = [] 17 | def dfs(root, sum, path): 18 | if not root: return 19 | if (sum - root.val == 0) and not (root.left or root.right): 20 | path.append(root.val) 21 | paths.append(path.copy()) 22 | path.append(root.val) 23 | dfs(root.left, sum-root.val, path.copy()) 24 | dfs(root.right, sum-root.val, path.copy()) 25 | path.pop(-1) 26 | dfs(root, sum, []) 27 | return paths -------------------------------------------------------------------------------- /python/CodingInterviews/offer36.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 二叉搜索树与双向链表 4 | Author: 5 | Charles 6 | ''' 7 | """ 8 | # Definition for a Node. 9 | class Node: 10 | def __init__(self, val, left=None, right=None): 11 | self.val = val 12 | self.left = left 13 | self.right = right 14 | """ 15 | 16 | class Solution: 17 | def treeToDoublyList(self, root: 'Node') -> 'Node': 18 | if not root: return 19 | self.prev, self.head = None, None 20 | def recur(root): 21 | if not root: return 22 | recur(root.left) 23 | if self.prev: 24 | self.prev.right, root.left = root, self.prev 25 | else: 26 | self.head = root 27 | self.prev = root 28 | recur(root.right) 29 | recur(root) 30 | self.head.left, self.prev.right = self.prev, self.head 31 | return self.head -------------------------------------------------------------------------------- /python/SortingAlgorithm/CountingSort.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 计数排序 4 | Author: 5 | Charles 6 | 微信公众号: 7 | Charles的皮卡丘 8 | ''' 9 | import random 10 | 11 | 12 | '''计数排序(假设都是0/正整数)''' 13 | def CountingSort(array): 14 | length = len(array) 15 | max_value = max(array) 16 | count = [0 for _ in range(max_value+1)] 17 | output = [0 for _ in range(length)] 18 | for i in range(length): 19 | count[array[i]] += 1 20 | for i in range(1, len(count)): 21 | count[i] += count[i-1] 22 | for i in range(length): 23 | output[count[array[i]]-1] = array[i] 24 | count[array[i]] -= 1 25 | return output 26 | 27 | 28 | '''test''' 29 | if __name__ == '__main__': 30 | array = [random.randint(0, 100) for _ in range(10)] 31 | array_sort = CountingSort(array.copy()) 32 | print('INPUT:\n%s' % ','.join([str(i) for i in array])) 33 | print('OUTPUT:\n%s' % ','.join([str(i) for i in array_sort])) -------------------------------------------------------------------------------- /python/CodingInterviews/offer32III.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 从上到下打印二叉树 III 4 | Author: 5 | Charles 6 | ''' 7 | # Definition for a binary tree node. 8 | # class TreeNode: 9 | # def __init__(self, x): 10 | # self.val = x 11 | # self.left = None 12 | # self.right = None 13 | 14 | class Solution: 15 | def levelOrder(self, root: TreeNode) -> List[List[int]]: 16 | if not root: return [] 17 | res, queue, flag = [], [[root]], True 18 | while queue: 19 | res_lvl, next_lvl, nodes = [], [], queue.pop(0) 20 | for node in nodes: 21 | res_lvl.append(node.val) 22 | if node.left: next_lvl.append(node.left) 23 | if node.right: next_lvl.append(node.right) 24 | if not flag: res_lvl = res_lvl[::-1] 25 | if next_lvl: queue.append(next_lvl) 26 | if res_lvl: res.append(res_lvl) 27 | flag = not flag 28 | return res -------------------------------------------------------------------------------- /python/SortingAlgorithm/QuickSort.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 快速排序 4 | Author: 5 | Charles 6 | 微信公众号: 7 | Charles的皮卡丘 8 | ''' 9 | import random 10 | 11 | 12 | '''快速排序''' 13 | def QuickSort(array, left, right): 14 | if left >= right: 15 | return array 16 | pivot, i, j = array[left], left, right 17 | while i < j: 18 | while i < j and array[j] >= pivot: 19 | j -= 1 20 | array[i] = array[j] 21 | while i < j and array[i] <= pivot: 22 | i += 1 23 | array[j] = array[i] 24 | array[j] = pivot 25 | QuickSort(array, left, i-1) 26 | QuickSort(array, i+1, right) 27 | return array 28 | 29 | 30 | '''test''' 31 | if __name__ == '__main__': 32 | array = [random.randint(0, 100) for _ in range(10)] 33 | array_sort = QuickSort(array.copy(), 0, len(array)-1) 34 | print('INPUT:\n%s' % ','.join([str(i) for i in array])) 35 | print('OUTPUT:\n%s' % ','.join([str(i) for i in array_sort])) -------------------------------------------------------------------------------- /python/SortingAlgorithm/MergeSort.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 归并排序 4 | Author: 5 | Charles 6 | 微信公众号: 7 | Charles的皮卡丘 8 | ''' 9 | import random 10 | 11 | 12 | '''数组合并''' 13 | def Merge(array_1, array_2): 14 | result = [] 15 | while array_1 and array_2: 16 | if array_1[0] < array_2[0]: 17 | result.append(array_1.pop(0)) 18 | else: 19 | result.append(array_2.pop(0)) 20 | if array_1: 21 | result += array_1 22 | if array_2: 23 | result += array_2 24 | return result 25 | 26 | 27 | '''归并排序''' 28 | def MergeSort(array): 29 | if len(array) < 2: return array 30 | pointer = len(array) // 2 31 | left = array[:pointer] 32 | right = array[pointer:] 33 | return Merge(MergeSort(left), MergeSort(right)) 34 | 35 | 36 | '''test''' 37 | if __name__ == '__main__': 38 | array = [random.randint(0, 100) for _ in range(10)] 39 | array_sort = MergeSort(array.copy()) 40 | print('INPUT:\n%s' % ','.join([str(i) for i in array])) 41 | print('OUTPUT:\n%s' % ','.join([str(i) for i in array_sort])) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 CharlesPikachu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /python/SortingAlgorithm/HeapSort.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 堆排序 4 | Author: 5 | Charles 6 | 微信公众号: 7 | Charles的皮卡丘 8 | ''' 9 | import random 10 | 11 | 12 | '''堆化''' 13 | def heapify(array, length, i): 14 | largest = i 15 | left = 2 * i + 1 16 | right = 2 * i + 2 17 | if left < length and array[largest] < array[left]: 18 | largest = left 19 | if right < length and array[largest] < array[right]: 20 | largest = right 21 | if largest != i: 22 | array[i], array[largest] = array[largest], array[i] 23 | heapify(array, length, largest) 24 | 25 | 26 | '''堆排序''' 27 | def HeapSort(array): 28 | length = len(array) 29 | for i in range(length, -1, -1): 30 | heapify(array, length, i) 31 | for i in range(length-1, 0, -1): 32 | array[i], array[0] = array[0], array[i] 33 | heapify(array, i, 0) 34 | return array 35 | 36 | 37 | '''test''' 38 | if __name__ == '__main__': 39 | array = [random.randint(0, 100) for _ in range(10)] 40 | array_sort = HeapSort(array.copy()) 41 | print('INPUT:\n%s' % ','.join([str(i) for i in array])) 42 | print('OUTPUT:\n%s' % ','.join([str(i) for i in array_sort])) -------------------------------------------------------------------------------- /python/CodingInterviews/offer29.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 顺时针打印矩阵 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def spiralOrder(self, matrix: List[List[int]]) -> List[int]: 9 | if not matrix: return [] 10 | left = 0 11 | right = len(matrix[0]) - 1 12 | top = 0 13 | bottom = len(matrix) - 1 14 | out = [] 15 | while True: 16 | # left -> right 17 | for i in range(left, right+1): 18 | out.append(matrix[top][i]) 19 | top += 1 20 | if top > bottom: break 21 | # top -> bottom 22 | for i in range(top, bottom+1): 23 | out.append(matrix[i][right]) 24 | right -= 1 25 | if left > right: break 26 | # right -> left 27 | for i in range(right, left-1, -1): 28 | out.append(matrix[bottom][i]) 29 | bottom -= 1 30 | if top > bottom: break 31 | # bottom -> top 32 | for i in range(bottom, top-1, -1): 33 | out.append(matrix[i][left]) 34 | left += 1 35 | if left > right: break 36 | return out -------------------------------------------------------------------------------- /python/CodingInterviews/offer20.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 表示数值的字符串 4 | Author: 5 | Charles 6 | ''' 7 | class Solution: 8 | def isNumber(self, s: str) -> bool: 9 | states = [ 10 | {' ': 0, 's': 1, 'd': 2, '.': 4}, # 0. start with 'blank' 11 | {'d': 2, '.': 4} , # 1. 'sign' before 'e' 12 | {'d': 2, '.': 3, 'e': 5, ' ': 8}, # 2. 'digit' before 'dot' 13 | {'d': 3, 'e': 5, ' ': 8}, # 3. 'digit' after 'dot' 14 | {'d': 3}, # 4. 'digit' after 'dot' (‘blank’ before 'dot') 15 | {'s': 6, 'd': 7}, # 5. 'e' 16 | {'d': 7}, # 6. 'sign' after 'e' 17 | {'d': 7, ' ': 8}, # 7. 'digit' after 'e' 18 | {' ': 8} # 8. end with 'blank' 19 | ] 20 | pointer = 0 21 | while s: 22 | c, s = s[0], s[1:] 23 | if c >= '0' and c <= '9': r = 'd' 24 | elif c in '+-': r = 's' 25 | elif c in 'eE': r = 'e' 26 | elif c in '.': r = '.' 27 | elif c in ' ': r = ' ' 28 | else: r = 'none' 29 | if r not in states[pointer]: return False 30 | pointer = states[pointer][r] 31 | return pointer in [2, 3, 7, 8] -------------------------------------------------------------------------------- /python/CodingInterviews/offer37.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Function: 3 | 序列化二叉树 4 | Author: 5 | Charles 6 | ''' 7 | # Definition for a binary tree node. 8 | # class TreeNode(object): 9 | # def __init__(self, x): 10 | # self.val = x 11 | # self.left = None 12 | # self.right = None 13 | 14 | class Codec: 15 | def serialize(self, root): 16 | if not root: return '[]' 17 | nums, queue = [], [root] 18 | while queue: 19 | node = queue.pop(0) 20 | if node: 21 | nums.append(str(node.val)) 22 | queue.append(node.left) 23 | queue.append(node.right) 24 | else: 25 | nums.append('null') 26 | return '[' + ','.join(nums) + ']' 27 | def deserialize(self, data): 28 | if data == '[]': return 29 | data = data[1: -1].split(',') 30 | root = TreeNode(int(data[0])) 31 | queue, pointer = [root], 1 32 | while queue and pointer < len(data): 33 | node = queue.pop(0) 34 | if data[pointer] != 'null': 35 | node.left = TreeNode(int(data[pointer])) 36 | queue.append(node.left) 37 | pointer += 1 38 | if data[pointer] != 'null': 39 | node.right = TreeNode(int(data[pointer])) 40 | queue.append(node.right) 41 | pointer += 1 42 | return root --------------------------------------------------------------------------------