├── .gitignore ├── 450. DeleteNodeInBST.py ├── README.md ├── decorator.py ├── number_of_Islands.py ├── 动态规划 ├── best-time-to-buy-and-sell-stock.py ├── climbing-stairs.py ├── coin-change-2.py ├── coin-change.py ├── combination-sum-iv.py ├── cutting_rope.py ├── dungeon_game.py ├── maximum-subarray.py ├── perfect-squares.py └── target-sum.py ├── 字符串 ├── 反转字符串中的单词.py ├── 无重复字符的最长子串.py └── 最长回文子串.py ├── 排序 ├── heapSort.py ├── 冒泡算法.py ├── 快速排序.py └── 最小的k个数.py ├── 搜索 ├── 回溯 │ ├── leetcode22括号生成.py │ ├── 全排列.py │ └── 机器人的最大路径.py ├── 广度优先遍历.py └── 深度优先遍历.py ├── 数组 ├── 1.数组中重复数字.py ├── 2.不修改数组找出重复的数字.py ├── 3.二维数组中的查找.py ├── 4.替换空格.py ├── 5. 旋转数组的最小数字.py ├── Maximum_Subarray.py ├── pascals-triangle-ii.py ├── pascals-triangle.py ├── three_sum.py ├── two sum.py ├── 两数之和.py ├── 合并排序的数组.py └── 数据流中的中位数.py ├── 栈 ├── __init__.py ├── 用两个栈实现队列.py └── 用两个队列实现一个栈.py ├── 树 ├── 1.重建二叉树.py ├── 116填充每个节点的下一个右侧节点指针.py ├── BFS.py ├── __init__.py ├── binaryTreeRightSideView.py ├── 二叉树的下一个节点.py ├── 二叉树的层次遍历.py ├── 二叉树的镜像.py ├── 对称的二叉树.py ├── 平衡二叉树.py ├── 树的子结构.py ├── 矩阵中的路径.py └── 路径总和.py ├── 递归和循环 ├── 1.斐波那契数列.py ├── 1.斐波那契数列(使用生成器).py ├── 2.青蛙跳台阶.py └── __init__.py └── 链表 ├── 2.add_two_sum.py ├── Remove Duplicates from Sorted List II.py ├── Remove Duplicates from Sorted List.py ├── __init__.py ├── merge_two_sorted_list.py ├── palindrome-linked-list.py ├── remove-nth-node-from-end-of-list.py ├── sort-list.py ├── 从尾到头打印链表.py └── 输出链表倒数第n个节点.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | cover/ 54 | 55 | # Translations 56 | *.mo 57 | *.pot 58 | 59 | # Django stuff: 60 | *.log 61 | local_settings.py 62 | db.sqlite3 63 | db.sqlite3-journal 64 | 65 | # Flask stuff: 66 | instance/ 67 | .webassets-cache 68 | 69 | # Scrapy stuff: 70 | .scrapy 71 | 72 | # Sphinx documentation 73 | docs/_build/ 74 | 75 | # PyBuilder 76 | .pybuilder/ 77 | target/ 78 | 79 | # Jupyter Notebook 80 | .ipynb_checkpoints 81 | 82 | # IPython 83 | profile_default/ 84 | ipython_config.py 85 | 86 | # pyenv 87 | # For a library or package, you might want to ignore these files since the code is 88 | # intended to run in multiple environments; otherwise, check them in: 89 | # .python-version 90 | 91 | # pipenv 92 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 93 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 94 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 95 | # install all needed dependencies. 96 | #Pipfile.lock 97 | 98 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 99 | __pypackages__/ 100 | 101 | # Celery stuff 102 | celerybeat-schedule 103 | celerybeat.pid 104 | 105 | # SageMath parsed files 106 | *.sage.py 107 | 108 | # Environments 109 | .env 110 | .venv 111 | env/ 112 | venv/ 113 | ENV/ 114 | env.bak/ 115 | venv.bak/ 116 | 117 | # Spyder project settings 118 | .spyderproject 119 | .spyproject 120 | 121 | # Rope project settings 122 | .ropeproject 123 | 124 | # mkdocs documentation 125 | /site 126 | 127 | # mypy 128 | .mypy_cache/ 129 | .dmypy.json 130 | dmypy.json 131 | 132 | # Pyre type checker 133 | .pyre/ 134 | 135 | # pytype static type analyzer 136 | .pytype/ 137 | 138 | # Cython debug symbols 139 | cython_debug/ 140 | 141 | # static files generated from Django application using `collectstatic` 142 | media 143 | static 144 | -------------------------------------------------------------------------------- /450. DeleteNodeInBST.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def insertIntoBST(self, root: TreeNode, val: int) -> TreeNode: 3 | if root == None: 4 | return TreeNode(val, None, None) 5 | if val > root.val: 6 | root.right = self.insertIntoBST(root.right, val) 7 | if val < root.val: 8 | root.left = self.insertIntoBST(root.left, val) 9 | return root 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # -Python- 2 | ### 《剑指offer》Python语言实现 3 | 本仓库主要记录自己刷《剑指offer》练习的记录,主要使用Python语言 4 | 代码经过调试,测试,可以直接运行,而且带有大量注释,希望大家一起多多交流 5 | -------------------------------------------------------------------------------- /decorator.py: -------------------------------------------------------------------------------- 1 | import time 2 | def func(f): 3 | def wrapper(f): 4 | time1 = time.time() 5 | f() 6 | time2 = time.time() 7 | return time2-time1 8 | return wrapper -------------------------------------------------------------------------------- /number_of_Islands.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def numIslands(self, grid: List[List[str]]) -> int: 3 | num = 0 4 | for i in range(len(grid)): 5 | for j in range(len(grid[0])): 6 | if grid[i][j] == "1": 7 | num += 1 8 | self.dfs(grid, i, j) 9 | return num 10 | 11 | def dfs(self, grid, m, n): 12 | # 不在网格内或者为“0”则终止递归 13 | if not self.isInGrid(grid, m, n) or grid[m][n] == "0": 14 | return 15 | if grid[m][n] == "1": 16 | grid[m][n] = "0" 17 | # 遍历上下左右的网格 18 | self.dfs(grid, m-1, n) 19 | self.dfs(grid, m+1, n) 20 | self.dfs(grid, m, n-1) 21 | self.dfs(grid, m, n+1) 22 | 23 | def isInGrid(self, grid, i, j): 24 | return i < len(grid) and j < len(grid[0]) and i >= 0 and j >= 0 25 | -------------------------------------------------------------------------------- /动态规划/best-time-to-buy-and-sell-stock.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def maxProfit(self, prices: List[int]) -> int: 3 | if len(prices) == 1: 4 | return 0 5 | maxval = 0 6 | for i in range(1, len(prices)): 7 | if (prices[i] - min(prices[:i])) > maxval: 8 | maxval = prices[i] - min(prices[:i]) 9 | return maxval 10 | -------------------------------------------------------------------------------- /动态规划/climbing-stairs.py: -------------------------------------------------------------------------------- 1 | # https://leetcode-cn.com/problems/climbing-stairs/ 2 | class Solution: 3 | def climbStairs(self, n: int) -> int: 4 | # 和斐波那契数列一样 5 | a, b = 0,1 6 | for i in range(n+1): 7 | a, b = b, a+b 8 | return a 9 | -------------------------------------------------------------------------------- /动态规划/coin-change-2.py: -------------------------------------------------------------------------------- 1 | # https://leetcode-cn.com/problems/coin-change-2/ 2 | class Solution: 3 | def change(self, amount: int, coins: List[int]) -> int: 4 | dp = [0]*(amount+1) 5 | dp[0] = 1 6 | for coin in coins: 7 | for i in range(coin, amount+1): 8 | dp[i] += dp[i-coin] 9 | return dp[amount] 10 | -------------------------------------------------------------------------------- /动态规划/coin-change.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def coinChange(self, coins: List[int], amount: int) -> int: 3 | # 包括0,f(amount)一共amount+1个元素 4 | dp = [float('inf')]*(amount+1) 5 | # 初始值dp[0]=0 6 | dp[0] = 0 7 | for coin in coins: 8 | for i in range(coin, amount+1): 9 | dp[i] = min(dp[i], dp[i-coin]+1) 10 | return dp[amount] if dp[amount] != float('inf') else -1 11 | -------------------------------------------------------------------------------- /动态规划/combination-sum-iv.py: -------------------------------------------------------------------------------- 1 | # https://leetcode-cn.com/problems/combination-sum-iv/ 2 | class Solution: 3 | def combinationSum4(self, nums: List[int], target: int) -> int: 4 | dp = [0]*(target+1) 5 | dp[0] = 1 6 | for i in range(1, target+1): 7 | for num in nums: 8 | if i>=num: 9 | dp[i] += dp[i-num] 10 | return dp[target] 11 | -------------------------------------------------------------------------------- /动态规划/cutting_rope.py: -------------------------------------------------------------------------------- 1 | # https://leetcode-cn.com/problems/jian-sheng-zi-lcof/solution/jian-zhi-offer-14-i-jian-sheng-zi-huan-s-xopj/ 2 | # 剪绳子 https://leetcode-cn.com/problems/jian-sheng-zi-lcof/ 3 | def cuttingRope(n): 4 | if n < 2: 5 | return 0 6 | if n < 4: 7 | return n-1 8 | res = 1 9 | while n > 4: 10 | res *= 3 11 | n -= 3 12 | res = res*n 13 | return res -------------------------------------------------------------------------------- /动态规划/dungeon_game.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | ''' 4 | @ calculateMinimumHP 5 | @ param 6 | int[][] 7 | @ return 8 | int 9 | ''' 10 | def calculateMinimumHPByRecur(dungeon, row, col): 11 | if row>=len(dungeon) or col>=len(dungeon[0]): 12 | return sys.maxsize 13 | n, m = len(dungeon), len(dungeon[0]) 14 | if row == n-1 and col == m-1: 15 | if dungeon[row][col] > 0: 16 | return 0 17 | else: 18 | return -dungeon[row][col] 19 | # 分别计算往右走和往下走 20 | right = calculateMinimumHPByRecur(dungeon, row+1, col) 21 | bottom = calculateMinimumHPByRecur(dungeon, row, col+1) 22 | needHP = min(right, bottom)-dungeon[row][col] 23 | if needHP > 0: 24 | res = needHP 25 | else: 26 | res = 0 27 | return res+1 28 | 29 | def calculateMinimumHPByDp(dungeon): 30 | n, m = len(dungeon), len(dungeon[0]) 31 | # dp[i][j]表示从i, j出发可以救到公主的最小生命值 32 | dp = [[0]*m for _ in range(n)] 33 | dp[n-1][m-1] = max(-dungeon[n-1][m-1], 0) 34 | # if dungeon[n-1][m-1] > 0: 35 | # dp[n-1][m-1] = 0 36 | # else: 37 | # dp[n-1][m-1] = -dungeon[n-1][m-1]+1 38 | 39 | for i in range(n-2,-1,-1): 40 | dp[i][-1] = max(0, dp[i+1][-1] - dungeon[i][-1]) 41 | for j in range(m-2,-1,-1): 42 | dp[-1][j] = max(0, dp[-1][j+1] - dungeon[-1][j]) 43 | 44 | for i in range(n-2, -1, -1): 45 | for j in range(m-2, -1, -1): 46 | # right, bottom = _getValue(i-1, j, dp), _getValue(i, j-1, dp) 47 | # needHP = min(right, bottom)-dungeon[i][j] 48 | # dp[i][j] = needHP if needHP > 0 else 0 49 | dp[i][j] = max(0, min(dp[i+1][j], dp[i][j+1]) - dungeon[i][j]) 50 | 51 | return dp[0][0]+1 52 | 53 | # def _getValue(i, j, arr): 54 | # n, m = len(arr), len(arr[0]) 55 | # if i>n-1 or j>m-1 or i<0 or j<0: 56 | # return sys.maxsize 57 | # return arr[i][j] 58 | 59 | if __name__ == '__main__': 60 | dungeon = [[-2,-3,3],[-5,-10,1],[10,30,-5]] 61 | print(calculateMinimumHPByRecur(dungeon, 0, 0), calculateMinimumHPByDp(dungeon)) -------------------------------------------------------------------------------- /动态规划/maximum-subarray.py: -------------------------------------------------------------------------------- 1 | # https://leetcode-cn.com/problems/maximum-subarray/ 2 | class Solution: 3 | def maxSubArray(self, nums: List[int]) -> int: 4 | maxval = nums[0] 5 | for i in range(1, len(nums)): 6 | if nums[i]+nums[i-1] > nums[i]: 7 | nums[i] += nums[i-1] 8 | if nums[i] > maxval: 9 | maxval = nums[i] 10 | return maxval 11 | -------------------------------------------------------------------------------- /动态规划/perfect-squares.py: -------------------------------------------------------------------------------- 1 | #https://leetcode-cn.com/problems/perfect-squares/ 2 | class Solution: 3 | def numSquares(self, n: int) -> int: 4 | nums = [x*x for x in range(int(n**0.5)+1)] 5 | dp = [float('inf')]*(n+1) 6 | dp[0] = 0 7 | for num in nums: 8 | for i in range(num, n+1): 9 | dp[i] = min(dp[i], dp[i-num]+1) 10 | return dp[n] 11 | -------------------------------------------------------------------------------- /动态规划/target-sum.py: -------------------------------------------------------------------------------- 1 | # https://leetcode-cn.com/problems/target-sum/ 2 | class Solution: 3 | def findTargetSumWays(self, nums: List[int], target: int) -> int: 4 | # 设nums和为s, 5 | # 由方程 6 | if (sum(nums)+target)%2 != 0 or sum(nums) < target: 7 | return 0 8 | neg = (sum(nums)+target)//2 9 | # 问题转化为找neg的值 10 | dp = [0]*(neg+1) 11 | dp[0] = 1 12 | for num in nums: 13 | i = neg 14 | while i >= 0 and i >= num: 15 | dp[i] += dp[i-num] 16 | i -= 1 17 | return dp[neg] 18 | -------------------------------------------------------------------------------- /字符串/反转字符串中的单词.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def reverseWords(self, s: str) -> str: 3 | L = s.split(" ") 4 | for i in range(len(L)): 5 | L[i] = L[i][::-1] 6 | return " ".join(L) 7 | 8 | # 错误代码 9 | def reverseWords(self, s: str) -> str: 10 | L = s.split(" ") 11 | for i in L: 12 | # 这里的i并没有赋值到L,所以不对 13 | i = i[::-1] 14 | return " ".join(L) -------------------------------------------------------------------------------- /字符串/无重复字符的最长子串.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # from leetcode 3 | def lengthOfLongestSubstring(self, s: str) -> int: 4 | # 哈希集合,记录每个字符是否出现过 5 | occ = set() 6 | n = len(s) 7 | # 右指针,初始值为 -1,相当于我们在字符串的左边界的左侧,还没有开始移动 8 | rk, ans = -1, 0 9 | for i in range(n): 10 | if i != 0: 11 | # 左指针向右移动一格,移除一个字符 12 | occ.remove(s[i - 1]) 13 | while rk + 1 < n and s[rk + 1] not in occ: 14 | # 不断地移动右指针 15 | occ.add(s[rk + 1]) 16 | rk += 1 17 | # 第 i 到 rk 个字符是一个极长的无重复字符子串 18 | ans = max(ans, rk - i + 1) 19 | return ans 20 | 21 | class Solution2: 22 | def lengthOfLongestSubstring(self, s: str) -> int: 23 | occ = set() 24 | right = 0 25 | res = 0 26 | for i in range(len(s)): 27 | if i != 0: 28 | occ.remove(s[i-1]) 29 | while right < len(s) and s[right] not in occ: 30 | occ.add(s[right]) 31 | right += 1 32 | res = max(res, right-i) 33 | return res -------------------------------------------------------------------------------- /字符串/最长回文子串.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # from leetcodes 3 | def longestPalindrome(self, s: str) -> str: 4 | n = len(s) 5 | dp = [[False] * n for _ in range(n)] 6 | ans = "" 7 | # 枚举子串的长度 l+1 8 | for l in range(n): 9 | # 枚举子串的起始位置 i,这样可以通过 j=i+l 得到子串的结束位置 10 | for i in range(n): 11 | j = i + l 12 | if j >= len(s): 13 | break 14 | if l == 0: 15 | dp[i][j] = True 16 | elif l == 1: 17 | dp[i][j] = (s[i] == s[j]) 18 | else: 19 | dp[i][j] = (dp[i + 1][j - 1] and s[i] == s[j]) 20 | if dp[i][j] and l + 1 > len(ans): 21 | ans = s[i:j+1] 22 | return ans 23 | -------------------------------------------------------------------------------- /排序/heapSort.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def sortArray(self, nums): 3 | def swap(nums, i ,j): 4 | nums[i], nums[j] = nums[j], nums[i] 5 | 6 | def heapify(tree, i, n): 7 | if i > n: 8 | return 9 | c1 = 2*i+1 10 | c2 = 2*i+2 11 | maxval = i 12 | if c1 < n and tree[maxval] < tree[c1]: 13 | maxval = c1 14 | if c2 < n and tree[maxval] < tree[c2]: 15 | maxval = c2 16 | if maxval != i: 17 | swap(tree, i, maxval) 18 | # ?? 19 | heapify(tree, maxval, n) 20 | 21 | def buildHeap(tree): 22 | # import math 23 | # for i in range(math.floor(len(tree)/2),-1,-1): 24 | # heapify(tree,i, len(tree)) 25 | n = len(tree) 26 | lastnode = n-1 27 | parent = (lastnode-1)//2 28 | # 这里i是-1,不是0 29 | for i in range(parent, -1,-1): 30 | heapify(tree, i, n) 31 | 32 | 33 | buildHeap(nums) 34 | length = len(nums) 35 | for j in range(length-1, 0, -1): 36 | swap(nums, j, 0) 37 | heapify(nums, 0, j) 38 | return nums 39 | -------------------------------------------------------------------------------- /排序/冒泡算法.py: -------------------------------------------------------------------------------- 1 | def bubbleSort(nums): 2 | L = len(nums) 3 | for i in range(L-1, 0, -1): 4 | for j in range(i): 5 | if nums[j] > nums[j+1]: 6 | nums[j], nums[j+1] = nums[j+1], nums[j] 7 | return nums 8 | 9 | 10 | if __name__ == '__main__': 11 | nums = [1,4,2,6,2,0] 12 | print(bubbleSort(nums)) -------------------------------------------------------------------------------- /排序/快速排序.py: -------------------------------------------------------------------------------- 1 | def quickSort(nums, start, end): 2 | if start >= end: 3 | # 递归的终止条件 4 | return 5 | left = start 6 | right = end 7 | mid = nums[start] 8 | 9 | while left < right: 10 | while nums[left] < mid and left < right: 11 | left += 1 12 | nums[left] = nums[right] 13 | while nums[right] > mid and left < right: 14 | right -= 1 15 | nums[right] = nums[left] 16 | # 退出循环后,left和right的值相同 17 | nums[left] = mid 18 | quickSort(nums, left+1, right) 19 | quickSort(nums, left, right-1) 20 | 21 | 22 | if __name__ == '__main__': 23 | nums = [1,2,4,6,1] 24 | quickSort(nums, 0, len(nums)-1) 25 | print(nums) 26 | -------------------------------------------------------------------------------- /排序/最小的k个数.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def smallestK(self, arr, k): 3 | def quicksort(nums, start ,end): 4 | # 退出递归 5 | if start >= end: 6 | return 7 | # 这里是nums[start],不是nums[0] 8 | mid = nums[start] 9 | low = start 10 | high = end 11 | 12 | while low < high: 13 | # 其中有一个要使用=,否则循环不退出 14 | # 这里要先判断high。不然会报错 15 | while low < high and nums[high] > mid: 16 | high -= 1 17 | nums[low] = nums[high] 18 | while low < high and nums[low] <= mid: 19 | low += 1 20 | nums[high] = nums[low] 21 | 22 | 23 | nums[low] = mid 24 | 25 | quicksort(nums, start, low-1) 26 | quicksort(nums, low+1, end) 27 | quicksort(arr, 0, len(arr)-1) 28 | return arr[:k] -------------------------------------------------------------------------------- /搜索/回溯/leetcode22括号生成.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def generateParenthesis(self, n: int): 3 | """ 4 | 左括号:Left小于N 5 | 右括号:right小于n,而且左括号数量大于右括号数量 6 | :param n: 7 | :return: 8 | """ 9 | """ 10 | 思路:使用DFS 11 | 1)当前左右括号都有大于 0个可以使用的时候,才产生分支; 12 | 13 | 2)产生左分支的时候,只看当前是否还有左括号可以使用; 14 | 15 | 3)产生右分支的时候,还受到左分支的限制,右边剩余可以使用的括号数量一定得在严格大于左边剩余的数量的时候,才可以产生分支; 16 | 17 | 4)在左边和右边剩余的括号数都等于 0的时候结算。 18 | 19 | 作者:liweiwei1419 20 | 链接:https://leetcode-cn.com/problems/generate-parentheses/solution/hui-su-suan-fa-by-liweiwei1419/ 21 | 来源:力扣(LeetCode) 22 | 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 23 | """ 24 | L = [] 25 | def dfs(s, left, right): 26 | if left == 0 and right == 0: 27 | L.append(s) 28 | return 29 | if left > 0: 30 | dfs(s+'(', left-1, right) 31 | if right > 0 and left < right: 32 | dfs(s+')', left, right-1) 33 | dfs('', n, n) 34 | return L 35 | 36 | -------------------------------------------------------------------------------- /搜索/回溯/全排列.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def permute(self, nums: List[int]) -> List[List[int]]: 6 | def dfs(nums, size, depth, path, used, res): 7 | if depth == size: 8 | res.append(path) 9 | return 10 | 11 | for i in range(size): 12 | if not used[i]: 13 | used[i] = True 14 | path.append(nums[i]) 15 | 16 | dfs(nums, size, depth + 1, path, used, res) 17 | 18 | used[i] = False 19 | path.pop() 20 | 21 | size = len(nums) 22 | if len(nums) == 0: 23 | return [] 24 | 25 | used = [False for _ in range(size)] 26 | res = [] 27 | dfs(nums, size, 0, [], used, res) 28 | return res 29 | 30 | 31 | if __name__ == '__main__': 32 | nums = [1, 2, 3] 33 | solution = Solution() 34 | res = solution.permute(nums) 35 | print(res) 36 | 37 | from rest_framework.views import APIView 38 | -------------------------------------------------------------------------------- /搜索/回溯/机器人的最大路径.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def movingCount(self, m: int, n: int, k: int) : 3 | count = 0 4 | visited = [[False]*n for i in range(m)] 5 | def g(x): 6 | # 计算x和y坐标的值 7 | s = 0 8 | while x>0: 9 | s += x%10 10 | x = x//10 11 | return s 12 | 13 | def f(m, n, k, x, y, count): 14 | if x<0 or x>=m or y<0 or y>=n or visited[x][y] or g(x)+g(y)>k: 15 | return 16 | count += 1 17 | visited[x][y] = True 18 | f(m, n, k, x - 1, y, count) 19 | f(m, n, k, x + 1, y,count) 20 | f(m, n, k, x, y + 1,count) 21 | f(m, n, k,x, y - 1,count) 22 | f(m,n,k,0,0,count) 23 | return count 24 | 25 | if __name__ == '__main__': 26 | solution = Solution() 27 | print(solution.movingCount(2,2,3)) 28 | 29 | # class Solution: 30 | # def movingCount(self, m: int, n: int, k: int) : 31 | # visited = [[False]*n for i in range(m)] 32 | # def f(m, n, k, x, y, count): 33 | # if x<0 or x>=m or y<0 or y>=n or (x % 10 + x // 10 + y % 10 + y // 10 > k or visited[x][y]: 34 | # return count 35 | # else: 36 | # count += 1 37 | # 38 | # return f(m, n, k, x - 1, y, count) + f(m, n, k, x + 1, y,count) + f(m, n, k, x, y + 1,count) + f(m, n, k,x, y - 1,count) 39 | # return f(m,n,k,0,0,0) 40 | 41 | 42 | # if x<0 or x>=n or y<0 or y>=m or not visited[x][y]: 43 | # return count 44 | # # 这里不一定是两位数 45 | # if x % 10 + x // 10 + y % 10 + y // 10 <= k: 46 | # count += 1 47 | # visited[x][y] = True 48 | # else: 49 | # return count 50 | 51 | -------------------------------------------------------------------------------- /搜索/广度优先遍历.py: -------------------------------------------------------------------------------- 1 | def widthSearch(root): 2 | queue = [] 3 | queue.append(root) 4 | while queue: 5 | print(queue.pop(0)) 6 | if root.left != None: 7 | queue.append(root.left) 8 | if root.right != None: 9 | queue.append(root.right) 10 | -------------------------------------------------------------------------------- /搜索/深度优先遍历.py: -------------------------------------------------------------------------------- 1 | def deepSearch(root): 2 | if root == None: 3 | return 4 | print(root) 5 | deepSearch(root.left) 6 | deepSearch(root.right) 7 | 8 | -------------------------------------------------------------------------------- /数组/1.数组中重复数字.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | class Solution: 3 | # 这里要特别注意~找到任意重复的一个值并赋值到duplication[0] 4 | # 函数返回True/False 5 | """ 6 | 总结: 7 | 前面首先要加上两个循环,如果数组为空,返回false, 8 | 如果数组有负数,或者有元素大于最大索引值,也返回false 9 | 扫描数组,设数组元素下标为i,下标为i的元素为m,比较i和m的值, 10 | 如果相等,继续扫描下一个元素 11 | 如果不相等,比较下标为m的元素和m的值是否相等 12 | 如果相等,就找到了一个重复的元素 13 | 如果不相等,把他们的值交换,依次进行下去 14 | """ 15 | def duplicate(self, numbers, duplication): 16 | # write code here 17 | if len(numbers) <= 0: 18 | return False 19 | for i in range(len(numbers)): 20 | if numbers[i] < 0 or numbers[i] > len(numbers) - 1: 21 | return False 22 | for i in range(len(numbers)): 23 | if numbers[i] == i: 24 | i += 1 25 | else: 26 | if numbers[numbers[i]] == numbers[i]: 27 | duplication[0] = numbers[numbers[i]] 28 | return True 29 | else: 30 | numbers[numbers[i]], numbers[i] = numbers[i], numbers[numbers[i]] 31 | return False 32 | 33 | 34 | -------------------------------------------------------------------------------- /数组/2.不修改数组找出重复的数字.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strugglehonor/leetcode/cca8b9a08a5ecc7df268e10b9690a440fec8124a/数组/2.不修改数组找出重复的数字.py -------------------------------------------------------------------------------- /数组/3.二维数组中的查找.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def findNumberIn2DArray(self, matrix, target): 3 | if not matrix: 4 | return False 5 | col = len(matrix[0])-1 6 | row = 0 7 | while col>=0 and row target: 11 | col -= 1 12 | else: 13 | row += 1 14 | return False -------------------------------------------------------------------------------- /数组/4.替换空格.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def replaceSpace(self, s: str): 3 | a = [] 4 | for c in s: 5 | if c == ' ': 6 | a.append('%20') 7 | else: 8 | a.append(c) 9 | return ''.join(a) 10 | 11 | 12 | -------------------------------------------------------------------------------- /数组/5. 旋转数组的最小数字.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strugglehonor/leetcode/cca8b9a08a5ecc7df268e10b9690a440fec8124a/数组/5. 旋转数组的最小数字.py -------------------------------------------------------------------------------- /数组/Maximum_Subarray.py: -------------------------------------------------------------------------------- 1 | # https://leetcode-cn.com/problems/jian-sheng-zi-lcof/ 2 | # 连续子数组的最大和 3 | # 使用前缀和 4 | def maximun_subarray(nums): 5 | mysum = 0 6 | ans = nums[0] 7 | summin = 0 # 最小前缀和 8 | for i in range(len(nums)): 9 | mysum += nums[i] 10 | ans = max(mysum-summin, ans) 11 | summin = min(summin, mysum) 12 | return ans -------------------------------------------------------------------------------- /数组/pascals-triangle-ii.py: -------------------------------------------------------------------------------- 1 | # https://leetcode-cn.com/problems/pascals-triangle-ii/ 2 | class Solution: 3 | def getRow(self, rowIndex: int) -> List[int]: 4 | res = [[1]] 5 | while len(res) < rowIndex+1: 6 | newRow = [a+b for a,b in zip([0]+res[-1], res[-1]+[0])] 7 | res.append(newRow) 8 | return res[rowIndex] 9 | -------------------------------------------------------------------------------- /数组/pascals-triangle.py: -------------------------------------------------------------------------------- 1 | # https://leetcode-cn.com/problems/pascals-triangle/ 2 | class Solution: 3 | def generate(self, numRows: int) -> List[List[int]]: 4 | if numRows <= 0: 5 | return [] 6 | res = [[1]] 7 | while len(res) < numRows: 8 | newRows = [a+b for a,b in zip([0]+res[-1], res[-1]+[0])] 9 | res.append(newRows) 10 | return res 11 | -------------------------------------------------------------------------------- /数组/three_sum.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def threeSum(self, nums: List[int]) -> List[List[int]]: 3 | if len(nums) < 3: 4 | return [] 5 | 6 | nums.sort() 7 | res = [] 8 | for first in range(len(nums)): 9 | # i > 0是因为第一个不用排序 10 | if first > 0 and nums[first] == nums[first-1]: 11 | continue 12 | third = len(nums)-1 13 | target = -nums[first] 14 | # 第二个指针 15 | for second in range(first+1, len(nums)-1): 16 | if second > first + 1 and nums[second] == nums[second-1]: 17 | continue 18 | 19 | # 后指针一直往前移动(数值越小) 20 | while second < third and nums[second]+nums[third] > target: 21 | third -= 1 22 | if second >= third: 23 | break 24 | # if nums[second]+nums[third] < target: 25 | # break 26 | if nums[third] + nums[second] == target: 27 | res.append([nums[first], nums[second], nums[third]]) 28 | return res 29 | -------------------------------------------------------------------------------- /数组/two sum.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # 暴力解法 3 | def twoSum(self, nums: List[int], target: int) -> List[int]: 4 | result = [] 5 | for i in range(len(nums)): 6 | temp = i+1 7 | while temp < len(nums): 8 | if nums[i] + nums[temp] == target: 9 | return [i, temp] 10 | temp += 1 11 | return [] 12 | 13 | class Solution2: 14 | # 哈希表 15 | def twoSum(self, nums: List[int], target: int) -> List[int]: 16 | hashtable = dict() 17 | for i, num in enumerate(nums): 18 | if target - num in hashtable: 19 | return [hashtable[target - num], i] 20 | hashtable[nums[i]] = i 21 | return [] -------------------------------------------------------------------------------- /数组/两数之和.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # 暴力解法 3 | def twoSum(self, nums: List[int], target: int) -> List[int]: 4 | result = [] 5 | for i in range(len(nums)): 6 | temp = i+1 7 | while temp < len(nums): 8 | if nums[i] + nums[temp] == target: 9 | return [i, temp] 10 | temp += 1 11 | return [] 12 | 13 | class Solution2: 14 | # 哈希表 15 | def twoSum(self, nums: List[int], target: int) -> List[int]: 16 | hashtable = dict() 17 | for i, num in enumerate(nums): 18 | if target - num in hashtable: 19 | return [hashtable[target - num], i] 20 | hashtable[nums[i]] = i 21 | return [] -------------------------------------------------------------------------------- /数组/合并排序的数组.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | """ 3 | A, B 为两个排序数组 4 | """ 5 | def merge(self, A, m: int, B, n: int): 6 | """ 7 | Do not return anything, modify A in-place instead. 8 | """ 9 | # 这个题其实不难,只是要考虑一些特殊情况,以及and和or这些条件想清楚 10 | p = m+n-1 11 | pA = m-1 12 | pB = n-1 13 | while pA>=0 and pB>=0: 14 | if A[pA] > B[pB]: 15 | A[p] = A[pA] 16 | p -= 1 17 | pA-=1 18 | else: 19 | A[p] = A[pB] 20 | p -= 1 21 | pB-=1 22 | -------------------------------------------------------------------------------- /数组/数据流中的中位数.py: -------------------------------------------------------------------------------- 1 | from heapq import * 2 | class MedianFinder: 3 | 4 | def __init__(self): 5 | """ 6 | initialize your data structure here. 7 | """ 8 | self.A = [] # 小顶堆 9 | self.B = [] # 大顶堆 10 | 11 | def addNum(self, num: int) -> None: 12 | if len(self.A) == len(self.B): 13 | heappush(self.B, -num) 14 | heappush(self.A, -heappop(self.B)) 15 | else: 16 | heappush(self.A, num) 17 | heappush(self.B, -heappop(self.A)) 18 | 19 | 20 | def findMedian(self) -> float: 21 | return self.A[0] if len(self.A)!=len(self.B) else (self.A[0]-self.B[0])/2.0 22 | -------------------------------------------------------------------------------- /栈/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strugglehonor/leetcode/cca8b9a08a5ecc7df268e10b9690a440fec8124a/栈/__init__.py -------------------------------------------------------------------------------- /栈/用两个栈实现队列.py: -------------------------------------------------------------------------------- 1 | class CQueue: 2 | # 可以利用一个栈进行放元素,然后把这个栈里面的元素弹出移到另外一个栈 3 | 4 | def __init__(self): 5 | self.stackA = [] 6 | self.stackB = [] 7 | 8 | def appendTail(self, value: int) -> None: 9 | self.stackA.append(value) 10 | 11 | def deleteHead(self) -> int: 12 | if len(self.stackA) == 0 and len(self.stackB) == 0: 13 | return -1 14 | if not self.stackB: 15 | while self.stackA: 16 | self.stackB.append(self.stackA.pop()) 17 | return self.stackB.pop() 18 | else: 19 | return self.stackB.pop() 20 | 21 | 22 | 23 | # Your CQueue object will be instantiated and called as such: 24 | # obj = CQueue() 25 | # obj.appendTail(value) 26 | # param_2 = obj.deleteHead() -------------------------------------------------------------------------------- /栈/用两个队列实现一个栈.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strugglehonor/leetcode/cca8b9a08a5ecc7df268e10b9690a440fec8124a/栈/用两个队列实现一个栈.py -------------------------------------------------------------------------------- /树/1.重建二叉树.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | class TreeNode: 3 | def __init__(self, x): 4 | self.val = x 5 | self.left = None 6 | self.right = None 7 | 8 | class Solution: 9 | # 前序遍历第一个节点是根节点,根据根节点的值找到这个值在中序遍历里面的索引, 10 | # 然后划分为左右子树,递归重复这个过程 11 | def buildTree(self, preorder, inorder): 12 | if len(inorder) == 0 and len(preorder)==0: 13 | return None 14 | root = TreeNode(preorder[0]) 15 | mid = inorder.index(root.val) 16 | # 这里是root.left,不是left 17 | root.left = self.buildTree(preorder[1:mid+1], inorder[0:mid]) 18 | root.right = self.buildTree(preorder[mid+1: ], inorder[mid+1: ]) 19 | return root 20 | -------------------------------------------------------------------------------- /树/116填充每个节点的下一个右侧节点指针.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def connect(self, root: 'Node') -> 'Node': 3 | if root == None: 4 | return root 5 | self.addTwoNode(root.left, root.right) 6 | return root 7 | def addTwoNode(self, node1, node2): 8 | if node1 == None or node2 == None: 9 | return 10 | # 把这两个节点连接起来 11 | node1.next = node2 12 | self.addTwoNode(node1.left, node1.right) 13 | self.addTwoNode(node2.left, node2.right) 14 | # 连接父节点不同的两个节点 15 | self.addTwoNode(node1.right, node2.left) 16 | -------------------------------------------------------------------------------- /树/BFS.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def levelOrder(self, root: TreeNode) -> List[List[int]]: 3 | if root == None: 4 | return [] 5 | queue = [] 6 | res = [] 7 | queue.append(root) 8 | while queue: 9 | n = len(queue) 10 | level = [] 11 | for i in range(n): 12 | node = queue.pop(0) 13 | level.append(node.val) 14 | if node.left != None: 15 | queue.append(node.left) 16 | if node.right != None: 17 | queue.append(node.right) 18 | res.append(level) 19 | return res 20 | -------------------------------------------------------------------------------- /树/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strugglehonor/leetcode/cca8b9a08a5ecc7df268e10b9690a440fec8124a/树/__init__.py -------------------------------------------------------------------------------- /树/binaryTreeRightSideView.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def rightSideView(self, root: TreeNode) -> List[int]: 3 | res = [] 4 | depth = 0 5 | self.dfs(root, res, depth) 6 | return res 7 | 8 | def dfs(self, root, array, depth): 9 | if root == None: 10 | return 11 | if depth == len(array): 12 | array.append(root.val) 13 | depth += 1 14 | self.dfs(root.right, array, depth) 15 | self.dfs(root.left, array, depth) 16 | 17 | -------------------------------------------------------------------------------- /树/二叉树的下一个节点.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strugglehonor/leetcode/cca8b9a08a5ecc7df268e10b9690a440fec8124a/树/二叉树的下一个节点.py -------------------------------------------------------------------------------- /树/二叉树的层次遍历.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode: 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class Solution: 9 | def levelOrder(self, root) : 10 | if not root: 11 | return [] 12 | queue = [] 13 | queue.append(root) 14 | L = [] 15 | while queue: 16 | node = queue.pop(0) 17 | L.append(node.val) 18 | if node.left != None: 19 | queue.append(node.left) 20 | if node.right != None: 21 | queue.append(node.right) 22 | return L -------------------------------------------------------------------------------- /树/二叉树的镜像.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def Mirror(self , pRoot): 3 | # write code here 4 | if pRoot == None: 5 | return pRoot 6 | 7 | tmp = pRoot.left 8 | pRoot.left = pRoot.right 9 | pRoot.right = tmp 10 | self.Mirror(pRoot.left) 11 | self.Mirror(pRoot.right) 12 | return pRoot 13 | -------------------------------------------------------------------------------- /树/对称的二叉树.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isSymmetric(self, root: TreeNode) -> bool: 3 | if root == None: 4 | return True 5 | return self.recur(root.left, root.right) 6 | def recur(self, rootA, rootB): 7 | if rootA == None and rootB == None: 8 | return True 9 | if rootA == None or rootB == None: 10 | return False 11 | if rootA.val != rootB.val: 12 | return False 13 | return self.recur(rootA.left, rootB.right) and self.recur(rootA.right, rootB.left) 14 | -------------------------------------------------------------------------------- /树/平衡二叉树.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isBalanced(self, root: TreeNode) -> bool: 3 | if root == None: 4 | return True 5 | if self.recur(root) == -1: 6 | return False 7 | else: 8 | return True 9 | 10 | def recur(self, root): 11 | # 返回值为-1,说明左子树不是平衡二叉树 12 | if root == None: 13 | return 0 14 | left = self.recur(root.left) 15 | if left == -1: 16 | return -1 17 | 18 | # 返回值为-1,说明右子树不是平衡二叉树 19 | right = self.recur(root.right) 20 | if right == -1: 21 | return -1 22 | 23 | # 是平衡二叉树,返回左右子树中较大高度的 24 | if abs(left-right) <= 1: 25 | return max(left, right)+1 26 | else: 27 | return -1 28 | -------------------------------------------------------------------------------- /树/树的子结构.py: -------------------------------------------------------------------------------- 1 | # https://leetcode-cn.com/problems/shu-de-zi-jie-gou-lcof/ 2 | class Solution: 3 | def isSubStructure(self, A: TreeNode, B: TreeNode) -> bool: 4 | if not A or not B:return False 5 | def recur(A, B): 6 | # 匹配完成 7 | if not B: return True 8 | if not A or A.val != B.val: return False 9 | return recur(A.left, B.left) and recur(A.right, B.right) 10 | return recur(A, B) or self.isSubStructure(A.left, B) or self.isSubStructure(A.right, B) 11 | -------------------------------------------------------------------------------- /树/矩阵中的路径.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strugglehonor/leetcode/cca8b9a08a5ecc7df268e10b9690a440fec8124a/树/矩阵中的路径.py -------------------------------------------------------------------------------- /树/路径总和.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def hasPathSum(self, root: TreeNode, targetSum: int) -> bool: 3 | if root == None: 4 | return False 5 | if root.left == None and root.right == None: 6 | return True if root.val == targetSum else False 7 | return self.hasPathSum(root.left, targetSum-root.val) or self.hasPathSum(root.right, targetSum-root.val) 8 | -------------------------------------------------------------------------------- /递归和循环/1.斐波那契数列.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | class Solution: 3 | # 这是《剑指offer》一样的解法,但是力扣上只打败了很少人 4 | def fib(self, n): 5 | a = [0,1] 6 | if n < 2: 7 | return a[n] 8 | fibA = 0 9 | fibB = 1 10 | for i in range(2, n+1): 11 | F = fibA + fibB 12 | fibA = fibB 13 | fibB = F 14 | return F -------------------------------------------------------------------------------- /递归和循环/1.斐波那契数列(使用生成器).py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import sys 4 | 5 | 6 | def fibonacci(n): # 生成器函数 - 斐波那契 7 | a, b, counter = 0, 1, 0 8 | while True: 9 | if (counter > n): 10 | return 11 | yield a 12 | a, b = b, a + b 13 | counter += 1 14 | 15 | 16 | f = fibonacci(10) # f 是一个迭代器,由生成器返回生成 17 | 18 | while True: 19 | try: 20 | print(next(f), end=" ") 21 | except StopIteration: 22 | sys.exit() 23 | -------------------------------------------------------------------------------- /递归和循环/2.青蛙跳台阶.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strugglehonor/leetcode/cca8b9a08a5ecc7df268e10b9690a440fec8124a/递归和循环/2.青蛙跳台阶.py -------------------------------------------------------------------------------- /递归和循环/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strugglehonor/leetcode/cca8b9a08a5ecc7df268e10b9690a440fec8124a/递归和循环/__init__.py -------------------------------------------------------------------------------- /链表/2.add_two_sum.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode: 3 | p, q = l1, l2 4 | # 进位 5 | add = 0 6 | # 数字位 7 | num = 0 8 | # 结果为返回dummy.next 9 | dummy = resNode = ListNode() 10 | while p or q: 11 | n = p.val if p else 0 12 | m = q.val if q else 0 13 | num = (m+n+add)%10 14 | add = (m+n+add)//10 15 | resNode.next = ListNode(num) 16 | resNode = resNode.next 17 | # 进行 18 | if p:p = p.next 19 | if q:q = q.next 20 | # 如果还有进位,需要加到末尾 21 | if add != 0: 22 | resNode.next = ListNode(add) 23 | # 注意resNode.next才是第一个节点 24 | return dummy.next 25 | -------------------------------------------------------------------------------- /链表/Remove Duplicates from Sorted List II.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def deleteDuplicates(self, head: ListNode) -> ListNode: 3 | if not head: 4 | return head 5 | dummy = p = ListNode(-120, head) 6 | while p.next and p.next.next: 7 | if p.next.val == p.next.next.val: 8 | x = p.next.val 9 | while p.next and x == p.next.val: 10 | p.next = p.next.next 11 | else: 12 | p = p.next 13 | return dummy.next 14 | -------------------------------------------------------------------------------- /链表/Remove Duplicates from Sorted List.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def deleteDuplicates(self, head: ListNode) -> ListNode: 3 | if not head: 4 | return head 5 | p = head 6 | while p and p.next and p.val == p.next.val: 7 | tmp = p.next.next 8 | if p.next: 9 | p.next.next = None 10 | p.next = tmp 11 | if p.val != p.next.val: 12 | p = p.next 13 | return head 14 | -------------------------------------------------------------------------------- /链表/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strugglehonor/leetcode/cca8b9a08a5ecc7df268e10b9690a440fec8124a/链表/__init__.py -------------------------------------------------------------------------------- /链表/merge_two_sorted_list.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode: 3 | if not l1:return l2 4 | if not l2:return l1 5 | prehead = ListNode(-1) 6 | prev = prehead 7 | while l1 and l2: 8 | if l1.val <= l2.val: 9 | prev.next = l1 10 | prev = prev.next 11 | l1 = l1.next 12 | else: 13 | prev.next = l2 14 | prev = prev.next 15 | l2 = l2.next 16 | prev.next = l1 if l1 != None else l2 17 | return prehead.next 18 | -------------------------------------------------------------------------------- /链表/palindrome-linked-list.py: -------------------------------------------------------------------------------- 1 | # https://leetcode-cn.com/problems/palindrome-linked-list/ 2 | class Solution: 3 | def isPalindrome(self, head: ListNode) -> bool: 4 | if not head: 5 | return False 6 | array = [] 7 | p = head 8 | while p: 9 | array.append(p.val) 10 | p = p.next 11 | return array == array[::-1] 12 | -------------------------------------------------------------------------------- /链表/remove-nth-node-from-end-of-list.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode: 3 | if head.next == None: 4 | return None 5 | former = ListNode() 6 | dummy = last = ListNode() 7 | former.next = head 8 | last.next = head 9 | for i in range(n): 10 | former = former.next 11 | while former != None and former.next != None: 12 | last = last.next 13 | former = former.next 14 | last.next = last.next.next if last.next else None 15 | return dummy.next 16 | -------------------------------------------------------------------------------- /链表/sort-list.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def sortList(self, head: ListNode) -> ListNode: 3 | if not head or not head.next: 4 | return head 5 | fast, slow = head.next, head 6 | while fast and fast.next: 7 | fast, slow = fast.next.next, slow.next 8 | nxt = slow.next 9 | slow.next = None 10 | left = self.sortList(head) 11 | right = self.sortList(nxt) 12 | # sort two ListNode 13 | dummy = p = ListNode(0) 14 | while left and right: 15 | if left.val < right.val: 16 | p.next = left 17 | left = left.next 18 | else: 19 | p.next = right 20 | right = right.next 21 | # p指针往后移动,容易漏 22 | p = p.next 23 | p.next = left if left else right 24 | return dummy.next 25 | -------------------------------------------------------------------------------- /链表/从尾到头打印链表.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 reversePrint(self, head): 9 | p = head 10 | a = [] 11 | while p!=None: 12 | a.insert(0, p.val) 13 | p = p.next 14 | return a -------------------------------------------------------------------------------- /链表/输出链表倒数第n个节点.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def getKthFromEnd(self, head: ListNode, k: int) -> ListNode: 3 | while not head:return head 4 | former, last = head, head 5 | for i in range(k): 6 | former = former.next 7 | while former != None: 8 | former = former.next 9 | last = last.next 10 | return last 11 | --------------------------------------------------------------------------------