├── .idea ├── .gitignore ├── inspectionProfiles │ └── profiles_settings.xml ├── misc.xml ├── modules.xml ├── pydatas-leecode.iml └── vcs.xml ├── 001.两数之和 ├── 答案.py └── 问题 ├── 002.计算两数之和(单向链表) ├── 答案.py └── 问题 ├── 003.最长子字符串,无重复字符 ├── 答案.py └── 问题 ├── 004.两个排序数组中的中间值 ├── 答案.py └── 问题 ├── 005.最长回文子串 ├── 答案.py └── 问题 ├── 006.之字型转换字符串 ├── 答案.py └── 题目 ├── 007.整数的逆序 ├── 答案.py └── 问题 ├── 008.字符串转成integer类型 ├── 答案.py └── 问题 ├── 009.回文数 ├── 答案.py └── 问题 ├── 010.正则表达式匹配 ├── 答案.py └── 问题 ├── 011.盛最多水的容器 ├── 答案.py └── 问题 ├── 012.整数转换成罗马数字 ├── 答案.py └── 问题 ├── 013.罗马数字转换成整数 ├── 答案.py └── 问题 ├── 014.最长公共前缀 ├── 答案.py └── 问题 ├── 015.三数之和 ├── 答案.py └── 问题 ├── 016.最接近给定值的三数之和 ├── 答案.py └── 问题 ├── 017.手机数字键中字母组合 ├── 答案.py └── 问题 ├── 018.四个数之和 ├── 答案.py └── 问题 ├── 019.删除链表的倒数第N个节点 ├── 答案.py └── 问题 ├── 020.有效的括号 ├── 答案.py └── 问题 ├── 021.合并两个有序链表 ├── 答案.py └── 问题 ├── 022.生成括号 ├── 答案.py └── 问题 ├── 023.合并排序链表 ├── 答案.py └── 问题 ├── 024.成对交换节点 └── 答案.py ├── 025.按组翻转链表 └── 答案.py ├── 026.从排序数组中删除重复项 └── 答案.py ├── 027.移除数组中指定元素 └── 答案.py ├── 028.找到子字符串第一次出现的位置 └── 答案.py ├── 029.分为两个整数 └── 答案.py ├── 030. 串联所有单词的子串 └── 答案.py ├── 031.全排列中的下一个 └── 答案.py ├── 032.最长有效括号对 └── 问题 ├── 033. 在旋转有序数组中搜索 └── 答案.py ├── 034.找一个值的范围 └── 答案.py ├── 035.将数插入数组中合适位置 └── 答案.py ├── 036.有效的数独 └── 答案.py ├── 037.填充数独 └── 答案.py ├── 038.计数和发言 └── 答案.py ├── 039.组合之和 └── 答案.py ├── 040.组合之和 II ├── 答案.py └── 题目 ├── 041首个未出现的正数 ├── 答案.py └── 题目 ├── 042.盛水量 ├── Answer.py └── Questio.md ├── 043.字符串相乘 ├── Answer.py └── Question.md ├── 044.通配符匹配 ├── Answer.py └── Question.txt ├── 045.跳跃游戏2 ├── Answer.py └── Question ├── 046.全排列 ├── Answer.py └── Question ├── 047排列2 ├── Answer.py └── Question ├── 048旋转图像 ├── Answer.py └── Question ├── 049字谜 ├── Answer.py └── Question ├── 050开方函数实现 ├── Answer.py └── Question ├── 051n皇后 ├── Answer └── Question.py ├── 052n皇后2 ├── Answer.py └── Question ├── 053最大子数组 ├── Answer.py └── Question ├── 054螺旋矩阵 ├── Answer.py └── Question ├── 055跳跃游戏 ├── Answer.py └── Question ├── 056合并间隔 ├── Answer.py └── Question ├── 057插入间隔 ├── Answer.py └── Question ├── 058字长 ├── Answer.py └── Question ├── 059螺旋矩阵 ├── Answer.py └── Question ├── 060排列顺序 ├── Answer.py └── Question ├── 061旋转列表 ├── Answer.py └── Question ├── 062唯一路径 ├── Answer.py └── Question ├── 063唯一路径2 ├── Answer.py └── Question ├── 064最小路径总和 ├── Answer.py └── Question ├── 065有效号码 ├── Answer.py └── Question ├── 066加一 ├── Answer.py └── Question ├── 067二进制加法 ├── Answer.py └── Question ├── 068文本对齐 ├── Answer.py └── Question ├── 069平方根实现 ├── Answer.py └── Question ├── 070爬楼梯 ├── Answer.py └── Question ├── 071简单路径 ├── Answer └── Question.py ├── 072编辑距离 ├── Answer.py └── Question ├── 073设置矩阵零 ├── Answer.py └── Question ├── 074搜索一个二维矩阵 ├── Answer.py └── Question ├── 075颜色排序 ├── Answer.py └── Question ├── 076最小窗口子串 ├── Answer.py └── Question ├── 077组合 ├── Answer.py └── Question ├── 078子集 ├── Answer.py └── Question ├── 079单词搜索 ├── Answer.py └── Question ├── 080删除排序数组中的重复项 ├── Answer.py └── Question ├── LICENSE └── README.md /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Datasource local storage ignored files 5 | /dataSources/ 6 | /dataSources.local.xml 7 | # Editor-based HTTP Client requests 8 | /httpRequests/ 9 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/pydatas-leecode.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /001.两数之和/答案.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def twoSum(self, nums, target): 3 | """ 4 | :nums类型: List[int] 5 | :目标类型: int 6 | :返回类型: List[int] 7 | """ 8 | d = {} 9 | for i, num in enumerate(nums): 10 | if target - num in d: 11 | return [d[target - num], i] 12 | d[num] = i 13 | # 没有特殊情况处理,因为它假定只有一个解决方案 -------------------------------------------------------------------------------- /001.两数之和/问题: -------------------------------------------------------------------------------- 1 | 2 | 给定一个整数数组,返回两个数字的索引,使得它们加起来成为一个特定的目标。 3 | 4 | 您可以假定每个输入都只有一个解决方案,并且您不能两次使用同一元素。 5 | 6 | 例: 7 | 8 | 给定nums = [2,7,11,15],目标= 9, 9 | 10 | 因为nums [0] + nums [1] = 2 + 7 = 9,所以返回[0,1]。 -------------------------------------------------------------------------------- /002.计算两数之和(单向链表)/答案.py: -------------------------------------------------------------------------------- 1 | #首先需要了解python单项链表的底层数据结构 2 | # 定义一个单项链表 3 | class ListNode(object): 4 | def __init__(self, x): 5 | self.val = x 6 | self.next = None 7 | class Solution(object): 8 | # 这个可能是初次想到的标准解决思路 9 | def _addTwoNumbers(self, l1, l2): 10 | """ 11 | :l1类型: ListNode 12 | :l2类型: ListNode 13 | :返回类型: ListNode 14 | """ 15 | p = dummy = ListNode(-1) 16 | carry = 0 17 | while l1 and l2: 18 | p.next = ListNode(l1.val + l2.val + carry) 19 | carry = p.next.val / 10 20 | p.next.val %= 10 #产生进位 21 | p = p.next 22 | l1 = l1.next 23 | l2 = l2.next 24 | 25 | res = l1 or l2 26 | while res: 27 | p.next = ListNode(res.val + carry) 28 | carry = p.next.val / 10 29 | p.next.val %= 10 30 | p = p.next 31 | res = res.next 32 | if carry: 33 | p.next = ListNode(1) 34 | return dummy.next 35 | 36 | 37 | # 更简短(灵性)的解决答案版本 38 | def addTwoNumbers(self, l1, l2): 39 | p = dummy = ListNode(-1) 40 | carry = 0 41 | while l1 or l2 or carry: 42 | val = (l1 and l1.val or 0) + (l2 and l2.val or 0) + carry 43 | carry = val / 10 44 | p.next = ListNode(val % 10) 45 | l1 = l1 and l1.next 46 | l2 = l2 and l2.next 47 | p = p.next 48 | return dummy.next -------------------------------------------------------------------------------- /002.计算两数之和(单向链表)/问题: -------------------------------------------------------------------------------- 1 | 题意:给出两个表示两个非负数的链表。 2 | 这些数字以相反的顺序存储,每个节点都包含一个数字。添加两个数字并将其作为链表返回。 3 | 分析题意,给出的链表的值都是非负数,如果两个数相加大于10 需要进位的话就向链表的后一个节点进位(这就是题目说的数字以相反的顺序存储),例如,输入是 (2 -> 4 -> 3) + (8 -> 6 -> 4) 那么输出应该是 0 -> 1 -> 8 ; 4 | 因为2+8需要向下一个节点进 1 ,4+6+1=11 需要向下一个节点进1 ,最后一个节点位置为 3+4+1=8 。 -------------------------------------------------------------------------------- /003.最长子字符串,无重复字符/答案.py: -------------------------------------------------------------------------------- 1 | import collections 2 | class Solution(object): 3 | def _lengthOfLongestSubstring(self, s): 4 | """ 5 | :数据s类型: str 6 | :返回类型: int 7 | """ 8 | d = collections.defaultdict(int) 9 | #该函数返回一个类似字典的对象。 10 | # defaultdict是Python内建字典类(dict)的一个子类,它重写了方法_missing_(key), 11 | # 增加了一个可写的实例变量default_factory,实例变量default_factory被missing()方法使用,如果该变量存在, 12 | # 则用以初始化构造器,如果没有,则为None。其它的功能和dict一样。 13 | l = ans = 0 14 | for i, c in enumerate(s): 15 | #enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标, 16 | # 一般用在 for 循环当中。 17 | while l > 0 and d[c] > 0: 18 | d[s[i - l]] -= 1 19 | l -= 1 20 | d[c] += 1 21 | l += 1 22 | ans = max(ans, l) 23 | return ans 24 | 25 | def lengthOfLongestSubstring(self, s): 26 | d = {} 27 | start = 0 28 | ans = 0 29 | for i, c in enumerate(s): 30 | if c in d: 31 | start = max(start, d[c] + 1) 32 | d[c] = i 33 | ans = max(ans, i - start + 1) 34 | return ans -------------------------------------------------------------------------------- /003.最长子字符串,无重复字符/问题: -------------------------------------------------------------------------------- 1 | 给定一个字符串,找到最长子字符串的长度直到遇见重复字符结束。 2 | 3 | 例子: 4 | 5 | 给定“ abcabcbb”,答案为“ abc”,长度为3。 6 | 7 | 给定“ bbbbb”,答案为“ b”,长度为1。 8 | 9 | 给定“ pwwkew”,答案为“ wke”,长度为3。请注意,答案必须是一个子字符串,“ pwke”是一个子序列,而不是子字符串。 10 | 11 | 后面会更新最长子序列问题,持续关注哦! -------------------------------------------------------------------------------- /004.两个排序数组中的中间值/答案.py: -------------------------------------------------------------------------------- 1 | # 二分操作效率较高 2 | class Solution(object): 3 | def findMedianSortedArrays(self, nums1, nums2): 4 | a, b = sorted((nums1, nums2), key=len) 5 | # 可以参考一下Python sorted() 函数的底层实现 6 | m, n = len(a), len(b) 7 | after = (m + n - 1) / 2 8 | lo, hi = 0, m 9 | while lo < hi: 10 | i = (lo + hi) / 2 11 | if after - i - 1 < 0 or a[i] >= b[after - i - 1]: 12 | hi = i 13 | else: 14 | lo = i + 1 15 | i = lo 16 | nextfew = sorted(a[i:i + 2] + b[after - i:after - i + 2]) 17 | return (nextfew[0] + nextfew[1 - (m + n) % 2]) / 2.0 18 | 19 | # sorted() 函数对所有可迭代的对象进行排序操作。 20 | # sort 与 sorted 区别: 21 | # sort 是应用在 list 上的方法,sorted 可以对所有可迭代的对象进行排序操作。 22 | # list 的 sort 方法返回的是对已经存在的列表进行操作,无返回值,而内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作。 -------------------------------------------------------------------------------- /004.两个排序数组中的中间值/问题: -------------------------------------------------------------------------------- 1 | 有两个大小分别为m和n的有序数组A和B。请找出这两个数组的中位数。你需要给出时间复杂度在O(log (m+n))以内的算法 2 | 例 1: 3 | 4 | nums1 = [1, 3] nums2 = [2] 5 | 6 | 中位数是 2.0 7 | 8 | 例 2: 9 | 10 | nums1 = [1, 2] nums2 = [3, 4] 11 | 12 | 中位数是 (2 + 3)/2 = 2.5 13 | 14 | 15 | -------------------------------------------------------------------------------- /005.最长回文子串/答案.py: -------------------------------------------------------------------------------- 1 | #暴力搜索(不推荐),与动态规划均可解 2 | class Solution(object): 3 | def longestPalindrome(self, s): 4 | """ 5 | :s的类型: str 6 | :返回值类型: str 7 | """ 8 | left = right = 0 9 | n = len(s) 10 | for i in range(n - 1): 11 | if 2 * (n - i) + 1 < right - left + 1: 12 | break 13 | l = r = i 14 | while l >= 0 and r < n and s[l] == s[r]: 15 | l -= 1 16 | r += 1 17 | if r - l - 2 > right - left: 18 | left = l + 1 19 | right = r - 1 20 | l = i 21 | r = i + 1 22 | while l >= 0 and r < n and s[l] == s[r]: 23 | l -= 1 24 | r += 1 25 | if r - l - 2 > right - left: 26 | left = l + 1 27 | right = r - 1 28 | return s[left:right + 1] 29 | 30 | -------------------------------------------------------------------------------- /005.最长回文子串/问题: -------------------------------------------------------------------------------- 1 | 最长回文子串 2 | 3 | 解释 4 | “回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。 5 | 6 | 给定字符串s,找到s中最长的回文子字符串。 您可以假设s的最大长度为1000()。 7 | 8 | 例: 9 | 10 | 输入:“ babad” 11 | 12 | 输出:“ bab” 13 | 14 | 注意:“ aba”也是有效答案。 15 | 16 | 例: 17 | 18 | 输入:“ cbbd” 19 | 20 | 输出:“ bb” -------------------------------------------------------------------------------- /006.之字型转换字符串/答案.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def convert(self, s, numRows): 3 | """ 4 | :s的类型: str 5 | :numRows类型: int 6 | :返回类型: str 7 | """ 8 | if numRows <= 1: 9 | return s 10 | n = len(s) 11 | ans = [] 12 | step = 2 * numRows - 2 13 | for i in range(numRows): 14 | one = i 15 | two = -i 16 | while one < n or two < n: 17 | if 0 <= two < n and one != two and i != numRows - 1: 18 | ans.append(s[two]) 19 | if one < n: 20 | ans.append(s[one]) 21 | one += step 22 | two += step 23 | return "".join(ans) -------------------------------------------------------------------------------- /006.之字型转换字符串/题目: -------------------------------------------------------------------------------- 1 | 字符串“ PAYPALISHIRING”以Z字形模式写在给定的行数上,如下所示:(您可能希望以固定的字体显示此模式以提高可读性) 2 | P A H N 3 | A P L S I I G 4 | Y I R 5 | 然后一行一行地读取:“ PAHNAPLSIIGYIR” 6 | 编写代码,该代码将包含一个字符串,并根据行数进行此转换: 7 | 字符串转换(string text,int nRows); 8 | convert(“ PAYPALISHIRING”,3)应该返回“ PAHNAPLSIIGYIR”。 9 | 10 | 11 | 12 | 13 | 题目理解(参考): 14 | 15 | 就是要把字符串摆成一个之字型的,比如有一个字符串 "0123456789ABCDEF",转为 zigzag 如下所示: 16 | 当 n = 2 时: 17 | 18 | 0 2 4 6 8 A C E 19 | 1 3 5 7 9 B D F 20 | 21 | 当 n = 3 时: 22 | 23 | 0 4 8 C 24 | 1 3 5 7 9 B D F 25 | 2 6 A E 26 | 27 | 当 n = 4 时: 28 | 29 | 0 6 C 30 | 1 5 7 B D 31 | 2 4 8 A E 32 | 3 9 F -------------------------------------------------------------------------------- /007.整数的逆序/答案.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def reverse(self, x): 3 | """ 4 | :x的类型: int 5 | :返回值类型: int 6 | """ 7 | sign = x < 0 and -1 or 1 8 | x = abs(x) 9 | ans = 0 10 | while x: 11 | ans = ans * 10 + x % 10 12 | x /= 10 13 | return sign * ans if ans <= 0x7fffffff else 0 14 | 15 | #可以算一下 0x7FFFFFFF 是多少 16 | #每个十六进制数4bit,因此8位16进制是4个字节,刚好是一个int整型 17 | #F (十进制的16)的二进制码为 1111 18 | #7的二进制码为 0111 19 | #这样一来,整个整数 0x7FFFFFFF 的二进制表示就是除了首位是 0,其余都是1 20 | #就是说,这是最大的整型数 int(因为第一位是符号位,0 表示它是正数) -------------------------------------------------------------------------------- /007.整数的逆序/问题: -------------------------------------------------------------------------------- 1 | 整数的逆序 2 | 3 | 示例1:x = 123,返回321示例2:x = -123,返回-321 4 | 5 | 6 | 特殊数据处理: 7 | 8 | 你有想过吗 9 | 10 | 如果整数的最后一位为0,则输出应该是什么? 例如10、100等情况。 11 | 12 | 您是否注意到逆序整数可能溢出? 假设输入是一个32位整数,则1000000003的反向溢出。 您应该如何处理这种情况? 13 | 14 | 出于此问题的目的,假定反向整数溢出时函数返回0。 15 | 16 | 注意:假定输入为32位带符号整数。 当反向整数溢出时,您的函数应返回0。 -------------------------------------------------------------------------------- /008.字符串转成integer类型/答案.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def myAtoi(self, s): 3 | """ 4 | :需转换的类型 str: str 5 | :返回类型: int 6 | """ 7 | s = s.strip() 8 | sign = 1 9 | if not s: 10 | return 0 11 | if s[0] in ["+", "-"]: 12 | if s[0] == "-": 13 | sign = -1 14 | s = s[1:] 15 | ans = 0 16 | for c in s: 17 | if c.isdigit(): 18 | ans = ans * 10 + int(c) 19 | else: 20 | break 21 | ans *= sign 22 | if ans > 2147483647: #正确的值超出可表示值的范围 23 | return 2147483647 24 | if ans < -2147483648: 25 | return -2147483648 26 | return ans -------------------------------------------------------------------------------- /008.字符串转成integer类型/问题: -------------------------------------------------------------------------------- 1 | 实现atoi函数将字符串转换为整数。 2 | 3 | 提示:仔细考虑所有可能的输入情况。如果您想挑战,请不要在下面看对atoi的要求 4 | 5 | 6 | 7 | 8 | 9 | 10 | 对atoi的要求: 11 | 12 | 该函数首先丢弃必要的空白字符,直到找到第一个非空白字符。然后,从该字符开始,取一个可选的初始正负号,后跟尽可能多的数字,并将其解释为数值。 13 | 14 | 该字符串可以在形成整数的字符之后包含其他字符,这些其他字符将被忽略并且不会影响此函数的行为。 15 | 16 | 如果str中的非空白字符的第一个序列不是有效的整数,或者由于str为空或仅包含空白字符而没有这样的序列,则不执行任何转换。 17 | 18 | 如果无法执行有效的转换,则返回零值。如果正确的值超出可表示值的范围,则返回INT_MAX(2147483647)或INT_MIN(-2147483648)。 -------------------------------------------------------------------------------- /009.回文数/答案.py: -------------------------------------------------------------------------------- 1 | 2 | class Solution(object): 3 | 4 | # 比较平常的算法 5 | def _isPalindrome(self, x): 6 | """ 7 | :x类型: int 8 | :返回类型: bool 9 | """ 10 | z = x 11 | y = 0 12 | while x > 0: 13 | y = y * 10 + x % 10 14 | x /= 10 15 | return z == y 16 | 17 | 18 | 19 | # 更快的算法 20 | def isPalindrome(self, x): 21 | """ 22 | :x类型: int 23 | :返回类型: bool 24 | """ 25 | if x < 0 or (x != 0 and x % 10 == 0): 26 | return False 27 | half = 0 28 | while x > half: 29 | half = half * 10 + x % 10 30 | x /= 10 31 | return x == half or half / 10 == x -------------------------------------------------------------------------------- /009.回文数/问题: -------------------------------------------------------------------------------- 1 | 回文数是指正着读和倒着读都有一样的整数 2 | 3 | 4 | 5 | 我们应该都知道回文数是什么意思了,应该想到数组来存储数字,但是怎样进行判断呢。首先负数和0直接返回false, 6 | 7 | 再对数组中的第一位和最后一位比较,第二位和倒数第二位比较,因为回文数是高度对称的。 8 | 9 | 10 | -------------------------------------------------------------------------------- /010.正则表达式匹配/答案.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def isMatch(self, s, p): 3 | """ 4 | :s类型: str 5 | :p类型: str 6 | :返回类型: bool 7 | """ 8 | dp = [[False] * (len(p) + 1) for _ in range(len(s) + 1)] 9 | dp[0][0] = True 10 | for j in range(1, len(p) + 1): 11 | if p[j - 1] == "*": 12 | dp[0][j] = dp[0][j - 2] 13 | 14 | for i in range(1, len(s) + 1): 15 | for j in range(1, len(p) + 1): 16 | if p[j - 1] != "*": 17 | dp[i][j] = dp[i - 1][j - 1] and (s[i - 1] == p[j - 1] or p[j - 1] == ".") 18 | else: 19 | dp[i][j] = dp[i][j - 2] or dp[i - 1][j] and (p[j - 2] == s[i - 1] or p[j - 2] == ".") 20 | return dp[-1][-1] -------------------------------------------------------------------------------- /010.正则表达式匹配/问题: -------------------------------------------------------------------------------- 1 | 给定一个字符串 (s) 和一个字符模式 (p)。实现支持 '.' 和 '*' 的正则表达式匹配。 2 | 3 | 4 | 示例 1: 5 | 6 | 输入: 7 | s = "aa" 8 | p = "a" 9 | 输出: false 10 | 解释: "a" 无法匹配 "aa" 整个字符串。 11 | 12 | 示例 2: 13 | 14 | 输入: 15 | s = "aa" 16 | p = "a*" 17 | 输出: true 18 | 解释: '*' 代表可匹配零个或多个前面的元素, 即可以匹配 'a' 。因此, 重复 'a' 一次, 字符串可变为 "aa"。 19 | 20 | 示例 3: 21 | 22 | 输入: 23 | s = "ab" 24 | p = ".*" 25 | 输出: true 26 | 解释: ".*" 表示可匹配零个或多个('*')任意字符('.')。 27 | 28 | 示例 4: 29 | 30 | 输入: 31 | s = "aab" 32 | p = "c*a*b" 33 | 输出: true 34 | 解释: 'c' 可以不被重复, 'a' 可以被重复一次。因此可以匹配字符串 "aab"。 35 | 36 | 示例 5: 37 | 38 | 输入: 39 | s = "mississippi" 40 | p = "mis*is*p*." 41 | 输出: false 42 | -------------------------------------------------------------------------------- /011.盛最多水的容器/答案.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def maxArea(self, height): 3 | """ 4 | :height类型: List[int] 5 | :返回类型: int 6 | """ 7 | ans = left = 0 8 | right = len(height) - 1 9 | while left < right: 10 | ans = max(ans, (right - left) * min(height[left], height[right])) 11 | if height[left] <= height[right]: 12 | left += 1 13 | else: 14 | right -= 1 15 | return ans -------------------------------------------------------------------------------- /011.盛最多水的容器/问题: -------------------------------------------------------------------------------- 1 | 题目描述: 2 | 3 | 给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 4 | 5 | 说明:你不能倾斜容器,且 n 的值至少为 2。 6 | -------------------------------------------------------------------------------- /012.整数转换成罗马数字/答案.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def intToRoman(self, num): 3 | """ 4 | :num类型: int 5 | :返回类型: str 6 | """ 7 | ans = "" 8 | values = {"M": 1000, "D": 500, "C": 100, "L": 50, "X": 10, "V": 5, "I": 1} 9 | literals = ["M", "D", "C", "L", "X", "V", "I"] 10 | for idx in [0, 2, 4]: 11 | k = num / values[literals[idx]] 12 | re = (num % values[literals[idx]]) / values[literals[idx + 2]] 13 | ans += k * literals[idx] 14 | if re >= 9: 15 | ans += literals[idx + 2] + literals[idx] 16 | elif re >= 5: 17 | ans += literals[idx + 1] + (re - 5) * literals[idx + 2] 18 | elif re == 4: 19 | ans += literals[idx + 2] + literals[idx + 1] 20 | else: 21 | ans += re * literals[idx + 2] 22 | num %= values[literals[idx + 2]] 23 | return ans -------------------------------------------------------------------------------- /012.整数转换成罗马数字/问题: -------------------------------------------------------------------------------- 1 | 罗马数字是古罗马使用的数字系统,现今仍很常见。 2 | 罗马数字共有7个,即Ⅰ(1),Ⅴ(5),Ⅹ(10),Ⅼ(50),Ⅽ(100),Ⅾ(500),Ⅿ(1000)。 3 | 需要注意的是罗马数字中没有“0”。 4 | 5 | 6 | 给定一个整数,将其转换为罗马数字。 7 | 8 | 输入范围[1,3999]。 -------------------------------------------------------------------------------- /013.罗马数字转换成整数/答案.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def romanToInt(self, s): 3 | """ 4 | :s类型: str 5 | :返回类型: int 6 | """ 7 | d = {"I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000} 8 | ans = 0 9 | for i in range(0, len(s) - 1): 10 | c = s[i] 11 | cafter = s[i + 1] 12 | if d[c] < d[cafter]: 13 | ans -= d[c] 14 | else: 15 | ans += d[c] 16 | ans += d[s[-1]] 17 | return ans -------------------------------------------------------------------------------- /013.罗马数字转换成整数/问题: -------------------------------------------------------------------------------- 1 | 罗马数字是古罗马使用的数字系统,现今仍很常见。 2 | 罗马数字共有7个,即Ⅰ(1),Ⅴ(5),Ⅹ(10),Ⅼ(50),Ⅽ(100),Ⅾ(500),Ⅿ(1000)。 3 | 需要注意的是罗马数字中没有“0”。 4 | 5 | 6 | 给定罗马数字,将其转换为整数。 7 | 8 | 输入的罗马数字转换后保证在1到3999的范围内。 -------------------------------------------------------------------------------- /014.最长公共前缀/答案.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def longestCommonPrefix(self, strs): 3 | """ 4 | :type strs: List[str] 5 | :rtype: str 6 | """ 7 | if len(strs) == 0: 8 | return "" 9 | i = 0 10 | j = 0 11 | end = 0 12 | while j < len(strs) and i < len(strs[j]): 13 | if j == 0: 14 | char = strs[j][i] 15 | else: 16 | if strs[j][i] != char: 17 | break 18 | if j == len(strs) - 1: 19 | i += 1 20 | j = 0 21 | end += 1 22 | else: 23 | j += 1 24 | 25 | return strs[j][:end] 26 | 27 | -------------------------------------------------------------------------------- /014.最长公共前缀/问题: -------------------------------------------------------------------------------- 1 | 编写一个函数来寻找最长公共前缀字符串(连续)之间字符串数组。 2 | 3 | Example 1: 4 | 5 | Input: ["flower","flow","flight"] 6 | Output: "fl" 7 | 8 | Example 2: 9 | 10 | Input: ["dog","racecar","car"] 11 | Output: "" 12 | Explanation: There is no common prefix among the input strings. 13 | 14 | Note: 15 | 16 | 所有给定的输入是小写字母a-z。 -------------------------------------------------------------------------------- /015.三数之和/答案.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def threeSum(self, nums): 3 | """ 4 | :nums类型: List[int] 5 | :返回类型: List[List[int]] 6 | """ 7 | # 先排序然后双指针 8 | res = [] 9 | nums.sort() 10 | for i in range(0, len(nums)): 11 | if i > 0 and nums[i] == nums[i - 1]: 12 | continue 13 | target = 0 - nums[i] 14 | start, end = i + 1, len(nums) - 1 15 | while start < end: 16 | if nums[start] + nums[end] > target: 17 | end -= 1 18 | elif nums[start] + nums[end] < target: 19 | start += 1 20 | else: 21 | res.append((nums[i], nums[start], nums[end])) 22 | end -= 1 23 | start += 1 24 | while start < end and nums[end] == nums[end + 1]: 25 | end -= 1 26 | while start < end and nums[start] == nums[start - 1]: 27 | start += 1 28 | return res -------------------------------------------------------------------------------- /015.三数之和/问题: -------------------------------------------------------------------------------- 1 | 给定一个数组A,要求从A中找出这么三个元素a,b,c使得a + b + c = 0, 2 | 返回由这样的a、b、c构成的三元组,且要保证三元组是唯一的。(即任意的两个三元组,它们里面的元素不能完全相同) 3 | 4 | 5 | 即一组数,找出所有的三个数的情况,满足三个数相加和为0 -------------------------------------------------------------------------------- /016.最接近给定值的三数之和/答案.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def threeSumClosest(self, nums, target): 3 | """ 4 | :nums类型: List[int] 5 | :target类型: int 6 | :返回类型: int 7 | """ 8 | nums.sort() #还是先排序 9 | ans = 0 10 | diff = float("inf") 11 | for i in range(0, len(nums)): 12 | start, end = i + 1, len(nums) - 1 13 | while start < end: 14 | sum = nums[i] + nums[start] + nums[end] 15 | if sum > target: 16 | if abs(target - sum) < diff: 17 | diff = abs(target - sum) 18 | ans = sum 19 | end -= 1 20 | else: 21 | if abs(target - sum) < diff: 22 | diff = abs(target - sum) 23 | ans = sum 24 | start += 1 25 | return ans -------------------------------------------------------------------------------- /016.最接近给定值的三数之和/问题: -------------------------------------------------------------------------------- 1 | 给定n个整数的数组S,找出S中三个整数,使得总和为最接近给定数值。 2 | 返回三个整数的总和。 3 | 你可以假设每个输入将有一个确切的解决方案。 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 大体思路: 14 | 15 | 那么这道题让返回这个最接近于给定值的值,即要保证当前三数和跟给定值之间的差的绝对值最小, 16 | 所以需要定义一个变量 diff 用来记录差的绝对值,然后还是要先将数组排个序,然后开始遍历数组, 17 | 思路跟那道三数之和很相似,都是先确定一个数,然后用两个指针 left 和 right 来滑动寻找另外两个数, 18 | 每确定两个数,求出此三数之和,然后算和给定值的差的绝对值存在 newDiff 中, 19 | 然后和 diff 比较并更新 diff 和结果 closest 即可。 20 | 21 | 22 | -------------------------------------------------------------------------------- /017.手机数字键中字母组合/答案.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def letterCombinations(self, digits): 3 | """ 4 | : digits类型: str 5 | :返回类型: List[str] 6 | """ 7 | if len(digits) == 0: 8 | return [] 9 | 10 | d = {1: "", 2: "abc", 3: "def", 4: "ghi", 5: "jkl", 6: "mno", 7: "pqrs", 8: "tuv", 9: "wxyz"} 11 | #建立字典 12 | 13 | def dfs(digits, index, path, res, d): 14 | if index == len(digits): 15 | res.append("".join(path)) 16 | return 17 | 18 | digit = int(digits[index]) 19 | for c in d.get(digit, []): 20 | path.append(c) 21 | dfs(digits, index + 1, path, res, d) 22 | path.pop() 23 | 24 | res = [] 25 | dfs(digits, 0, [], res, d) 26 | return res -------------------------------------------------------------------------------- /017.手机数字键中字母组合/问题: -------------------------------------------------------------------------------- 1 | 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。 2 | 3 | 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 4 | 可以拿出老式的手机按键,更加直观 5 | 输入:"23" 6 | 输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]. 7 | 8 | 说明: 9 | 尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。 -------------------------------------------------------------------------------- /018.四个数之和/答案.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def fourSum(self, nums, target): 3 | """ 4 | :nums类型: List[int] 5 | :target类型: int 6 | :返回类型: List[List[int]] 7 | """ 8 | nums.sort() #整体思路,先排序再左右夹逼 9 | res = [] 10 | for i in range(0, len(nums)): 11 | if i > 0 and nums[i] == nums[i - 1]: 12 | continue 13 | for j in range(i + 1, len(nums)): 14 | if j > i + 1 and nums[j] == nums[j - 1]: 15 | continue 16 | start = j + 1 17 | end = len(nums) - 1 18 | while start < end: 19 | sum = nums[i] + nums[j] + nums[start] + nums[end] 20 | if sum < target: 21 | start += 1 22 | elif sum > target: 23 | end -= 1 24 | else: 25 | res.append((nums[i], nums[j], nums[start], nums[end])) 26 | start += 1 27 | end -= 1 28 | while start < end and nums[start] == nums[start - 1]: 29 | start += 1 30 | while start < end and nums[end] == nums[end + 1]: 31 | end -= 1 32 | return res -------------------------------------------------------------------------------- /018.四个数之和/问题: -------------------------------------------------------------------------------- 1 | 题目描述: 2 | 给定一个有n个整数的数组S和目标值target,找到其中所有由四个数a、b、c、d组成, 3 | 使得a + b + c + d = target 的四元组。如: 4 | 5 | given array S = [1, 0, -1, 0, -2, 2], and target = 0. 6 | A solution set is: 7 | [ 8 | [-1, 0, 0, 1], 9 | [-2, -1, 1, 2], 10 | [-2, 0, 0, 2] 11 | ] -------------------------------------------------------------------------------- /019.删除链表的倒数第N个节点/答案.py: -------------------------------------------------------------------------------- 1 | # 定义一个单链表过程. 2 | 3 | class ListNode(object): 4 | def __init__(self, x): 5 | self.val = x 6 | self.next = None 7 | 8 | class Solution(object): 9 | def removeNthFromEnd(self, head, n): 10 | """ 11 | :"头指针"类型: ListNode 12 | :n的类型: int 13 | :返回类型: ListNode 14 | """ 15 | dummy = ListNode(-1) 16 | dummy.next = head 17 | fast = slow = dummy 18 | 19 | while n and fast: 20 | fast = fast.next 21 | n -= 1 22 | 23 | while fast.next and slow.next: 24 | fast = fast.next 25 | slow = slow.next 26 | 27 | slow.next = slow.next.next 28 | return dummy.next -------------------------------------------------------------------------------- /019.删除链表的倒数第N个节点/问题: -------------------------------------------------------------------------------- 1 | 给定一个链表: 1->2->3->4->5, 和 n = 2. 2 | 当删除了倒数第二个节点后,链表变为 1->2->3->5. -------------------------------------------------------------------------------- /020.有效的括号/答案.py: -------------------------------------------------------------------------------- 1 | #python实现,直接利用栈 2 | 1. 3 | class Solution: 4 | def isValid(self, s): 5 | """ 6 | :type s: str 7 | :rtype: bool 8 | """ 9 | stack = list() 10 | for si in s: 11 | if si == '(': 12 | stack.append(')') 13 | elif si == '[': 14 | stack.append(']') 15 | elif si == '{': 16 | stack.append('}') 17 | elif len(stack) == 0 or si != stack.pop(): 18 | return False 19 | return len(stack) == 0 20 | 21 | 22 | 23 | # 2.利用词典 24 | class Solution(object): 25 | def isValid(self, s): 26 | """ 27 | :type s: str 28 | :rtype: bool 29 | """ 30 | stack = [] 31 | d = ["()", "[]", "{}"] 32 | for i in range(0, len(s)): 33 | stack.append(s[i]) 34 | if len(stack) >= 2 and stack[-2] + stack[-1] in d: 35 | stack.pop() 36 | stack.pop() 37 | return len(stack) == 0 -------------------------------------------------------------------------------- /020.有效的括号/问题: -------------------------------------------------------------------------------- 1 | 给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。 2 | 3 | 有效字符串需满足: 4 | 5 | 左括号必须用相同类型的右括号闭合。 6 | 左括号必须以正确的顺序闭合。 7 | 8 | 注意空字符串可被认为是有效字符串。 9 | 10 | 示例 1: 11 | 12 | 输入: "()" 13 | 输出: true 14 | 15 | 示例 2: 16 | 17 | 输入: "()[]{}" 18 | 输出: true 19 | 20 | 示例 3: 21 | 22 | 输入: "(]" 23 | 输出: false 24 | 25 | 示例 4: 26 | 27 | 输入: "([)]" 28 | 输出: false 29 | 30 | 示例 5: 31 | 32 | 输入: "{[]}" 33 | 输出: true -------------------------------------------------------------------------------- /021.合并两个有序链表/答案.py: -------------------------------------------------------------------------------- 1 | # 定义单链表. 2 | class ListNode(object): 3 | def __init__(self, x): 4 | self.val = x 5 | self.next = None 6 | 7 | class Solution(object): 8 | def mergeTwoLists(self, l1, l2): 9 | """ 10 | :l1类型: ListNode 11 | :l2类型: ListNode 12 | :返回类型: ListNode 13 | """ 14 | head = dummy = ListNode(-1) 15 | while l1 and l2: 16 | if l1.val < l2.val: 17 | head.next = l1 18 | l1 = l1.next 19 | else: 20 | head.next = l2 21 | l2 = l2.next 22 | head = head.next 23 | if l1: 24 | head.next = l1 25 | if l2: 26 | head.next = l2 27 | return dummy.next -------------------------------------------------------------------------------- /021.合并两个有序链表/问题: -------------------------------------------------------------------------------- 1 | 合并两个已排序的链表,并以新链表的形式返回。 2 | 新列表应该通过将前两个列表的节点拼接在一起来创建。 -------------------------------------------------------------------------------- /022.生成括号/答案.py: -------------------------------------------------------------------------------- 1 | # 1.递归解: 2 | class Solution: 3 | def generateParenthesis(self, n): 4 | """ 5 | :n的类型: int 6 | :返回类型: List[str] 7 | """ 8 | resList = [] 9 | def generate(left,right,res,n): 10 | if right == n: 11 | resList.append(res) 12 | else: 13 | if left < n: 14 | generate(left+1,right,res+'(',n) 15 | if right < n and right < left: 16 | generate(left,right+1,res+')',n) 17 | 18 | generate(0,0,'',n) 19 | 20 | return resList 21 | 22 | 23 | 24 | 25 | 26 | 27 | # 2.解题思路:列举出所有合法的括号匹配,使用深度优先搜索。如果左括号的数量大于右括号的数量的话,就不能产生合法的括号匹配。 28 | 29 | class Solution(object): 30 | def generateParenthesis(self, n): 31 | """ 32 | :n的类型: int 33 | :返回类型: List[str] 34 | """ 35 | 36 | def dfs(left, path, res, n): 37 | if len(path) == 2 * n: 38 | if left == 0: 39 | res.append("".join(path)) 40 | return 41 | 42 | if left < n: 43 | path.append("(") 44 | dfs(left + 1, path, res, n) 45 | path.pop() 46 | if left > 0: 47 | path.append(")") 48 | dfs(left - 1, path, res, n) 49 | path.pop() 50 | 51 | res = [] 52 | dfs(0, [], res, n) 53 | return res -------------------------------------------------------------------------------- /022.生成括号/问题: -------------------------------------------------------------------------------- 1 | 给定n对括号,编写一个函数以生成格式正确的括号的所有组合。 2 | 3 | 例如,给定n = 3,解决方案集为:[ "((()))", "(()())", "(())()", "()(())", "()()()" ] -------------------------------------------------------------------------------- /023.合并排序链表/答案.py: -------------------------------------------------------------------------------- 1 | # 定义一个单向链表 2 | class ListNode(object): 3 | def __init__(self, x): 4 | self.val = x 5 | self.next = None 6 | import heapq 7 | 8 | # 重写比较函数的功能 9 | ListNode.__lt__ = lambda x, y: (x.val < y.val) 10 | 11 | class Solution(object): 12 | def mergeKLists(self, lists): 13 | """ 14 | :lists类型: List[ListNode] 15 | :返回类型: ListNode 16 | """ 17 | heap = [] 18 | p = dummy = ListNode(-1) 19 | for i in range(0, len(lists)): 20 | node = lists[i] 21 | if not node: 22 | continue 23 | heapq.heappush(heap, node) 24 | 25 | while heap: 26 | value, node = heapq.heappop(heap) 27 | p.next = node 28 | p = p.next 29 | if node.next: 30 | node = node.next 31 | heapq.heappush(heap, node) 32 | return dummy.next -------------------------------------------------------------------------------- /023.合并排序链表/问题: -------------------------------------------------------------------------------- 1 | 合并k个排序的链表,并将其作为一个排序表返回。 分析并描述其复杂性。 -------------------------------------------------------------------------------- /024.成对交换节点/答案.py: -------------------------------------------------------------------------------- 1 | # 定义单链表 2 | # class ListNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.next = None 6 | 7 | class Solution(object): 8 | def swapPairs(self, head): 9 | 10 | def reverseList(head, k): 11 | pre = None 12 | cur = head 13 | while cur and k > 0: 14 | tmp = cur.next 15 | cur.next = pre 16 | pre = cur 17 | cur = tmp 18 | k -= 1 19 | head.next = cur 20 | return cur, pre 21 | 22 | if not head or not head.next: 23 | return head 24 | ret = head.next 25 | p = head 26 | pre = None 27 | while p: 28 | next, newHead = reverseList(p, 2) 29 | if pre: 30 | pre.next = newHead 31 | pre = p 32 | p = next 33 | return ret -------------------------------------------------------------------------------- /025.按组翻转链表/答案.py: -------------------------------------------------------------------------------- 1 | 2 | # 定义一个单向链表. 3 | # class ListNode(object): 4 | # def __init__(self, x): 5 | # self.val = x 6 | # self.next = None 7 | class Solution(object): 8 | def reverseKGroup(self, head, k): 9 | def reverseList(head, k): 10 | pre = None 11 | cur = head 12 | while cur and k > 0: 13 | tmp = cur.next 14 | cur.next = pre 15 | pre = cur 16 | cur = tmp 17 | k -= 1 18 | head.next = cur 19 | return cur, pre 20 | 21 | length = 0 22 | p = head 23 | while p: 24 | length += 1 25 | p = p.next 26 | if length < k: 27 | return head 28 | step = length / k 29 | ret = None 30 | pre = None 31 | p = head 32 | while p and step: 33 | next, newHead = reverseList(p, k) 34 | if ret is None: 35 | ret = newHead 36 | if pre: 37 | pre.next = newHead 38 | pre = p 39 | p = next 40 | step -= 1 41 | return ret -------------------------------------------------------------------------------- /026.从排序数组中删除重复项/答案.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def removeDuplicates(self, nums): 3 | if len(nums) <= 1: 4 | return len(nums) 5 | slow = 0 6 | for i in range(1, len(nums)): 7 | if nums[i] != nums[slow]: 8 | slow += 1 9 | nums[slow] = nums[i] 10 | return slow + 1 -------------------------------------------------------------------------------- /027.移除数组中指定元素/答案.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def removeElement(self, nums, val): 3 | """ 4 | :type nums: List[int] 5 | :type val: int 6 | :rtype: int 7 | """ 8 | slow = -1 9 | for i in range(0, len(nums)): 10 | if nums[i] != val: 11 | slow += 1 12 | nums[slow] = nums[i] 13 | return slow + 1 -------------------------------------------------------------------------------- /028.找到子字符串第一次出现的位置/答案.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def strStr(self, haystack, needle): 3 | """ 4 | :type haystack: str 5 | :type needle: str 6 | :rtype: int 7 | """ 8 | if len(haystack) == len(needle): 9 | if haystack == needle: 10 | return 0 11 | else: 12 | return -1 13 | 14 | for i in range(0, len(haystack)): 15 | k = i 16 | j = 0 17 | while j < len(needle) and k < len(haystack) and haystack[k] == needle[j]: 18 | j += 1 19 | k += 1 20 | if j == len(needle): 21 | return i 22 | return -1 if needle else 0 -------------------------------------------------------------------------------- /029.分为两个整数/答案.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def divide(self, dividend, divisor): 3 | if divisor == 0: 4 | return 0x7fffffff 5 | sign = 1 6 | if dividend * divisor < 0: 7 | sign = -1 8 | ans = 0 9 | cnt = 1 10 | dividend = abs(dividend) 11 | divisor = abs(divisor) 12 | subsum = divisor 13 | while dividend >= divisor: 14 | while (subsum << 1) <= dividend: 15 | cnt <<= 1 16 | subsum <<= 1 17 | ans += cnt 18 | cnt = 1 19 | dividend -= subsum 20 | subsum = divisor 21 | return max(min(sign * ans, 0x7fffffff), -2147483648) -------------------------------------------------------------------------------- /030. 串联所有单词的子串/答案.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | 4 | class Solution(object): 5 | def findSubstring(self, s, words): 6 | if len(words) > len(s): 7 | return [] 8 | d = {} 9 | t = {} 10 | ans = [] 11 | deq = deque([]) 12 | wl = len(words[0]) 13 | fullscore = 0 14 | for word in words: 15 | d[word] = d.get(word, 0) + 1 16 | fullscore += 1 17 | 18 | for i in range(0, len(s)): 19 | head = start = i 20 | t.clear() 21 | score = 0 22 | 23 | while start + wl <= len(s) and s[start:start + wl] in d: 24 | cword = s[start:start + wl] 25 | t[cword] = t.get(cword, 0) + 1 26 | if t[cword] <= d[cword]: 27 | score += 1 28 | else: 29 | break 30 | start += wl 31 | 32 | if score == fullscore: 33 | ans.append(head) 34 | 35 | return ans -------------------------------------------------------------------------------- /031.全排列中的下一个/答案.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def nextPermutation(self, nums): 3 | if nums is None or len(nums) <= 1: 4 | return 5 | 6 | pos = None 7 | p = len(nums) - 2 8 | while p >= 0: 9 | if nums[p + 1] > nums[p]: 10 | pos = p 11 | break 12 | p -= 1 13 | 14 | if pos is None: 15 | self.reverse(nums, 0, len(nums) - 1) 16 | return 17 | 18 | minPos, minV = pos + 1, nums[pos + 1] 19 | for i in range(pos + 1, len(nums)): 20 | if nums[i] <= minV and nums[i] > nums[pos]: 21 | minV = nums[i] 22 | minPos = i 23 | # 交换变量 24 | nums[pos], nums[minPos] = nums[minPos], nums[pos] 25 | self.reverse(nums, pos + 1, len(nums) - 1) 26 | 27 | def reverse(self, nums, start, end): 28 | while start < end: 29 | nums[start], nums[end] = nums[end], nums[start] 30 | start += 1 31 | end -= 1 -------------------------------------------------------------------------------- /032.最长有效括号对/问题: -------------------------------------------------------------------------------- 1 | 给定一个只有左括号"("和右括号")"的字符串,求合法的字符串有多长,合法的意思是说左括号必须出现在右括号的左边的情况视为合法情况。 2 | 例如:()(), (()),不合法的情况例如:)(,以前做过一个题目是判断是否合法,那么这道题目实际上是得到一个最长的合法子串,并输出该长度 -------------------------------------------------------------------------------- /033. 在旋转有序数组中搜索/答案.py: -------------------------------------------------------------------------------- 1 | # 二分搜索 2 | class Solution(object): 3 | def search(self, nums, target): 4 | 5 | if not nums: 6 | return -1 7 | left = 0 8 | right = len(nums) - 1 9 | while left <= right: 10 | mid = (right + left) / 2 11 | if nums[mid] == target: 12 | return mid 13 | if nums[mid] >= nums[left]: 14 | if nums[left] <= target <= nums[mid]: 15 | right = mid - 1 16 | else: 17 | left = mid + 1 18 | else: 19 | if nums[mid] <= target <= nums[right]: 20 | left = mid + 1 21 | else: 22 | right = mid - 1 23 | return -1 -------------------------------------------------------------------------------- /034.找一个值的范围/答案.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def searchRange(self, nums, target): 3 | l, r = 0, len(nums) - 1 4 | found = 0 5 | start, end = 0, 0 6 | while l < r: 7 | m = l + (r - l) / 2 8 | if target > nums[m]: 9 | l = m + 1 10 | else: 11 | if target == nums[m]: 12 | found += 1 13 | r = m - 1 14 | 15 | if nums[l] == target: 16 | found += 1 17 | 18 | start = r 19 | if nums[r] != target or r < 0: 20 | start = r + 1 21 | 22 | l, r = 0, len(nums) - 1 23 | while l < r: 24 | m = l + (r - l) / 2 25 | if target < nums[m]: 26 | r = m - 1 27 | else: 28 | if target == nums[m]: 29 | found += 1 30 | l = m + 1 31 | end = l 32 | if nums[l] != target: 33 | end = l - 1 34 | 35 | if found == 0: 36 | return [-1, -1] 37 | return [start, end] -------------------------------------------------------------------------------- /035.将数插入数组中合适位置/答案.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def searchInsert(self, nums, target): 3 | lo = 0 4 | hi = len(nums) 5 | while lo < hi: 6 | mid = lo + (hi - lo) / 2 7 | if nums[mid] > target: 8 | hi = mid 9 | elif nums[mid] < target: 10 | lo = mid + 1 11 | else: 12 | return mid 13 | return lo -------------------------------------------------------------------------------- /036.有效的数独/答案.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def isValidSudoku(self, board): 3 | cacheCol = [[0] * 9 for _ in range(0, 10)] 4 | cacheRow = [[0] * 9 for _ in range(0, 10)] 5 | cacheBox = [[0] * 9 for _ in range(0, 10)] 6 | 7 | for i in range(0, 9): 8 | for j in range(0, 9): 9 | ib = (i / 3) * 3 + j / 3 10 | if board[i][j] == ".": 11 | continue 12 | num = int(board[i][j]) - 1 13 | if cacheRow[i][num] != 0 or cacheCol[j][num] != 0 or cacheBox[ib][num] != 0: 14 | return False 15 | cacheRow[i][num] = 1 16 | cacheCol[j][num] = 1 17 | cacheBox[ib][num] = 1 18 | return True -------------------------------------------------------------------------------- /037.填充数独/答案.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def solveSudoku(self, board): 3 | cacheBox = [[0] * len(board) for _ in range(len(board))] 4 | cacheRow = [[0] * len(board) for _ in range(len(board))] 5 | cacheCol = [[0] * len(board) for _ in range(len(board))] 6 | 7 | def helper(board, i, j, cacheRow, cacheCol, cacheBox): 8 | if board[i][j] == ".": 9 | for k in range(1, 10): 10 | if i < 0 or i >= len(board) or j < 0 or j >= len(board): 11 | continue 12 | ib = (i / 3) * 3 + j / 3 13 | if cacheRow[i][k - 1] == 1 or cacheCol[j][k - 1] == 1 or cacheBox[ib][k - 1] == 1: 14 | continue 15 | 16 | cacheRow[i][k - 1] = cacheCol[j][k - 1] = cacheBox[ib][k - 1] = 1 17 | board[i][j] = str(k) 18 | if i == j == len(board) - 1: 19 | return True 20 | if i + 1 < len(board): 21 | if helper(board, i + 1, j, cacheRow, cacheCol, cacheBox): 22 | return True 23 | elif j + 1 < len(board): 24 | if helper(board, 0, j + 1, cacheRow, cacheCol, cacheBox): 25 | return True 26 | board[i][j] = "." 27 | cacheRow[i][k - 1] = cacheCol[j][k - 1] = cacheBox[ib][k - 1] = 0 28 | else: 29 | if i == j == len(board) - 1: 30 | return True 31 | if i + 1 < len(board): 32 | if helper(board, i + 1, j, cacheRow, cacheCol, cacheBox): 33 | return True 34 | elif j + 1 < len(board): 35 | if helper(board, 0, j + 1, cacheRow, cacheCol, cacheBox): 36 | return True 37 | return False 38 | 39 | for i in range(len(board)): 40 | for j in range(len(board)): 41 | if board[i][j] != ".": 42 | ib = (i / 3) * 3 + j / 3 43 | k = int(board[i][j]) - 1 44 | cacheRow[i][k] = cacheCol[j][k] = cacheBox[ib][k] = 1 45 | print 46 | helper(board, 0, 0, cacheRow, cacheCol, cacheBox) -------------------------------------------------------------------------------- /038.计数和发言/答案.py: -------------------------------------------------------------------------------- 1 | 2 | class Solution(object): 3 | def countAndSay(self, n): 4 | ans = "1" 5 | n -= 1 6 | while n > 0: 7 | res = "" 8 | pre = ans[0] 9 | count = 1 10 | for i in range(1, len(ans)): 11 | if pre == ans[i]: 12 | count += 1 13 | else: 14 | res += str(count) + pre 15 | pre = ans[i] 16 | count = 1 17 | res += str(count) + pre 18 | ans = res 19 | n -= 1 20 | return ans -------------------------------------------------------------------------------- /039.组合之和/答案.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def combinationSum(self, candidates, target): 3 | 4 | def dfs(candidates, start, target, path, res): 5 | if target == 0: 6 | return res.append(path + []) 7 | 8 | for i in range(start, len(candidates)): 9 | if target - candidates[i] >= 0: 10 | path.append(candidates[i]) 11 | dfs(candidates, i, target - candidates[i], path, res) 12 | path.pop() 13 | 14 | res = [] 15 | dfs(candidates, 0, target, [], res) 16 | return res -------------------------------------------------------------------------------- /040.组合之和 II/答案.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def combinationSum2(self, candidates, target): 3 | """ 4 | :type candidates: List[int] 5 | :type target: int 6 | :rtype: List[List[int]] 7 | """ 8 | 9 | def dfs(nums, target, start, visited, path, res): 10 | if target == 0: 11 | res.append(path + []) 12 | return 13 | 14 | for i in range(start, len(nums)): 15 | if i > start and nums[i] == nums[i - 1]: 16 | continue 17 | if target - nums[i] < 0: 18 | return 0 19 | if i not in visited: 20 | visited.add(i) 21 | path.append(nums[i]) 22 | dfs(nums, target - nums[i], i + 1, visited, path, res) 23 | path.pop() 24 | visited.discard(i) 25 | 26 | candidates.sort() 27 | res = [] 28 | visited = set([]) 29 | dfs(candidates, target, 0, visited, [], res) 30 | return res -------------------------------------------------------------------------------- /040.组合之和 II/题目: -------------------------------------------------------------------------------- 1 |  给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。 2 | 3 | candidates 中的每个数字在每个组合中只能使用一次。 4 | 5 | 说明:所有数字(包括目标数)都是正整数。解集不能包含重复的组合。  6 | 示例 1:输入: candidates = [10,1,2,7,6,1,5], target = 8, 7 | 所求解集为: 8 | 9 | [ [1, 7], [1, 2, 5], [2, 6], [1, 1, 6] ] 10 | -------------------------------------------------------------------------------- /041首个未出现的正数/答案.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def firstMissingPositive(self, nums): 3 | i = 0 4 | while i < len(nums): 5 | if 0 < nums[i] <= len(nums) and nums[nums[i] - 1] != nums[i]: 6 | nums[nums[i] - 1], nums[i] = nums[i], nums[nums[i] - 1] 7 | else: 8 | i += 1 9 | 10 | for i in range(0, len(nums)): 11 | if nums[i] != i + 1: 12 | return i + 1 13 | return len(nums) + 1 -------------------------------------------------------------------------------- /041首个未出现的正数/题目: -------------------------------------------------------------------------------- 1 | 给定一个未排序的整数数组,找到第一个丢失的正整数。 2 | 3 | 例如,给定[1,2,0]返回3,[3,4,-1,1]返回2。 4 | 5 | 算法应在O(n)时间内运行并使用固定的空间。 -------------------------------------------------------------------------------- /042.盛水量/Answer.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | class Solution: 4 | # @param A, a list of integers 5 | # @return an integer 6 | def trap(self, A): 7 | leftmosthigh = [0 for i in range(len(A))] 8 | leftmax = 0 9 | for i in range(len(A)): 10 | if A[i] > leftmax: leftmax = A[i] 11 | leftmosthigh[i] = leftmax 12 | sum = 0 13 | rightmax = 0 14 | for i in reversed(range(len(A))): 15 | if A[i] > rightmax: rightmax = A[i] 16 | if min(rightmax, leftmosthigh[i]) > A[i]: 17 | sum += min(rightmax, leftmosthigh[i]) - A[i] 18 | return sum 19 | 20 | 21 | class Solution(object): 22 | def trap(self, height): 23 | """ 24 | :type height: List[int] 25 | :rtype: int 26 | """ 27 | ans = left = 0 28 | right = len(height) - 1 29 | leftWall = rightWall = float("-inf") 30 | while left <= right: 31 | if leftWall <= rightWall: 32 | ans += max(0, leftWall - height[left]) 33 | leftWall = max(leftWall, height[left]) 34 | left += 1 35 | else: 36 | ans += max(0, rightWall - height[right]) 37 | rightWall = max(rightWall, height[right]) 38 | right -= 1 39 | return ans 40 | 41 | 42 | -------------------------------------------------------------------------------- /042.盛水量/Questio.md: -------------------------------------------------------------------------------- 1 | 给 n 个非负整数表示每个宽度为一的柱子的高度图,计算下雨之后能接多少水。 2 | 3 | 例如, 4 | 输入 [0,1,0,2,1,0,1,3,2,1,2,1],返回 6。 5 | 6 | 7 | 8 | 上面的高度图由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示,在这种情况下,可以接 6 个单位的雨水(蓝色部分)。  9 | 10 | 11 | 12 | 解题思路: 13 | 14 |     这道题目设计的非常巧妙,主要需要解决的问题是如何让左右两根很高的柱子中间填满,可以从左右同时网中间遍历,同时要找到左右两边最高的那根柱子,因为中间的都是要填满的。 15 | -------------------------------------------------------------------------------- /043.字符串相乘/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def multiply(self, num1, num2): 3 | """ 4 | :type num1: str 5 | :type num2: str 6 | :rtype: str 7 | """ 8 | ans = [0] * (len(num1) + len(num2)) 9 | for i, n1 in enumerate(reversed(num1)): 10 | for j, n2 in enumerate(reversed(num2)): 11 | ans[i + j] += int(n1) * int(n2) 12 | ans[i + j + 1] += ans[i + j] / 10 13 | ans[i + j] %= 10 14 | while len(ans) > 1 and ans[-1] == 0: 15 | ans.pop() 16 | return "".join(map(str, ans[::-1])) 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /043.字符串相乘/Question.md: -------------------------------------------------------------------------------- 1 | 给两个用字符串表示的数字,求它们的乘积。 2 | 3 | 注意:数字非负,且可以无限大 4 | 5 | 6 | 这道题让我们求两个字符串数字的相乘, 7 | 输入的两个数和返回的数都是以字符串格式储存的, 8 | 这样做的原因可能是这样可以计算超大数相乘, 9 | 可以不受 int 或 long 的数值范围的约束 10 | 11 | 12 | 13 | ----8 9 <- num2 14 | 15 | ----7 6 <- num1 16 | 17 | ----5 4 18 | 19 | --4 8 20 | 21 | --6 3 22 | 23 | 5 6 24 | 25 | ------- 26 | 6 7 6 4 -------------------------------------------------------------------------------- /044.通配符匹配/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def isMatch(self, s, p): 3 | """ 4 | :type s: str 5 | :type p: str 6 | :rtype: bool 7 | """ 8 | i = j = 0 9 | lenS = len(s) 10 | lenP = len(p) 11 | lastMatchPos = 0 12 | lastStarPos = -1 13 | while i < len(s): 14 | if j < lenP and p[j] in (s[i], "?"): 15 | i += 1 16 | j += 1 17 | elif j < lenP and p[j] == "*": 18 | lastMatchPos = i 19 | lastStarPos = j 20 | j += 1 21 | elif lastStarPos > -1: 22 | i = lastMatchPos + 1 23 | lastMatchPos += 1 24 | j = lastStarPos + 1 25 | else: 26 | return False 27 | while j < lenP and p[j] == "*": 28 | j += 1 29 | return j == lenP -------------------------------------------------------------------------------- /044.通配符匹配/Question.txt: -------------------------------------------------------------------------------- 1 | 实现通配符模式匹配并支持“?”和“ *”。'?'匹配任何单个字符。 2 | '*'匹配任何字符序列(包括空序列)。匹配项应覆盖整个输入字符串(而非部分)。 3 | 4 | 函数名应为:bool isMatch(const char * s,const char * p) 5 | 6 | 例如 7 | isMatch("aa","a") → false 8 | isMatch("aa","aa") → true 9 | isMatch("aaa","aa") → false 10 | isMatch("aa", "") → true 11 | isMatch("aa", "a") → true 12 | isMatch("ab", "?") → true 13 | isMatch("aab", "ca*b") → false 14 | 15 | -------------------------------------------------------------------------------- /045.跳跃游戏2/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def jump(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: int 6 | """ 7 | pos = 0 8 | ans = 0 9 | bound = len(nums) 10 | while pos < len(nums) - 1: 11 | dis = nums[pos] 12 | farthest = posToFarthest = 0 13 | for i in range(pos + 1, min(pos + dis + 1, bound)): 14 | canReach = i + nums[i] 15 | if i == len(nums) - 1: 16 | return ans + 1 17 | if canReach > farthest: 18 | farthest = canReach 19 | posToFarthest = i 20 | ans += 1 21 | pos = posToFarthest 22 | return ans -------------------------------------------------------------------------------- /045.跳跃游戏2/Question: -------------------------------------------------------------------------------- 1 | 给定一个非负整数数组,你最初位于数组的第一个位置。 2 | 3 | 数组中的每个元素代表你在该位置可以跳跃的最大长度。 4 | 5 | 你的目标是使用最少的跳跃次数到达数组的最后一个位置。 6 | 7 | 示例 8 | 9 | 输入: [2,3,1,1,4] 10 | 输出: 2 11 | 解释: 跳到最后一个位置的最小跳跃数是 2。 12 | 从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。 13 | -------------------------------------------------------------------------------- /046.全排列/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def permute(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: List[List[int]] 6 | """ 7 | res = [] 8 | visited = set([]) 9 | 10 | def dfs(nums, path, res, visited): 11 | if len(path) == len(nums): 12 | res.append(path + []) 13 | return 14 | 15 | for i in range(0, len(nums)): 16 | # if i > 0 and nums[i - 1] == nums[i]: 17 | # continue 18 | if i not in visited: 19 | visited.add(i) 20 | path.append(nums[i]) 21 | dfs(nums, path, res, visited) 22 | path.pop() 23 | visited.discard(i) 24 | 25 | dfs(nums, [], res, visited) 26 | return res -------------------------------------------------------------------------------- /046.全排列/Question: -------------------------------------------------------------------------------- 1 | 给定一个数组,返回他的所有排列。 2 | 3 | 例如,[1,2,3] 的全排列 4 | 5 | [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ] -------------------------------------------------------------------------------- /047排列2/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def permuteUnique(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: List[List[int]] 6 | """ 7 | res = [] 8 | nums.sort() 9 | 10 | def dfs(nums, res, path, visited): 11 | if len(path) == len(nums): 12 | res.append(path + []) 13 | return 14 | 15 | for i in range(len(nums)): 16 | if i in visited: 17 | continue 18 | if i > 0 and nums[i] == nums[i - 1] and i - 1 not in visited: 19 | continue 20 | visited |= {i} 21 | path.append(nums[i]) 22 | dfs(nums, res, path, visited) 23 | path.pop() 24 | visited -= {i} 25 | 26 | dfs(nums, res, [], set()) 27 | return res -------------------------------------------------------------------------------- /047排列2/Question: -------------------------------------------------------------------------------- 1 | 给定一组可能包含重复项的数字,请返回所有可能的唯一排列。 2 | 3 | 例如,[1,1,2]具有以下唯一排列: [[1,1,2],[1,2,1],[2,1,1]] -------------------------------------------------------------------------------- /048旋转图像/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def rotate(self, matrix): 3 | """ 4 | :type matrix: List[List[int]] 5 | :rtype: void Do not return anything, modify matrix in-place instead. 6 | """ 7 | if len(matrix) == 0: 8 | return 9 | h = len(matrix) 10 | w = len(matrix[0]) 11 | for i in range(0, h): 12 | for j in range(0, w / 2): 13 | matrix[i][j], matrix[i][w - j - 1] = matrix[i][w - j - 1], matrix[i][j] 14 | 15 | for i in range(0, h): 16 | for j in range(0, w - 1 - i): 17 | matrix[i][j], matrix[w - 1 - j][h - 1 - i] = matrix[w - 1 - j][h - 1 - i], matrix[i][j] -------------------------------------------------------------------------------- /048旋转图像/Question: -------------------------------------------------------------------------------- 1 | 您会得到一个表示图像的n x n 2D矩阵。 2 | 将图像旋转90度(顺时针)。 3 | 注意:您必须就地旋转图像,这意味着您必须直接修改输入 2D矩阵。 4 | 不要分配另一个2D矩阵并进行旋转。 5 | 范例1: 6 | 给定输入矩阵= [[1,2,3],[4,5,6],[7,8,9]], 7 | 就地旋转输入矩阵,使其变为:[[7,4,1],[8,5,2],[9,6,3]] 8 | 范例2: 9 | 给定输入矩阵= [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]], 10 | 就地旋转输入矩阵,使其变为:[[15,13,2,5],[14,3,4,1],[12,6,8,8,9],[16,7,10, 11 | 11] -------------------------------------------------------------------------------- /049字谜/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def groupAnagrams(self, strs): 3 | """ 4 | :type strs: List[str] 5 | :rtype: List[List[str]] 6 | """ 7 | 8 | def hash(count): 9 | p1, p2 = 2903, 29947 10 | ret = 0 11 | for c in count: 12 | ret = ret * p1 + c 13 | p1 *= p2 14 | return ret 15 | 16 | d = {} 17 | 18 | for str in strs: 19 | count = [0] * 26 20 | for c in str: 21 | count[ord(c) - ord('a')] += 1 22 | key = hash(count) 23 | if key not in d: 24 | d[key] = [str] 25 | else: 26 | d[key].append(str) 27 | return [d[k] for k in d] -------------------------------------------------------------------------------- /049字谜/Question: -------------------------------------------------------------------------------- 1 | 给定一个字符串数组,将字谜分组在一起。 2 | 例如,给定:[“ eat”,“ tea”,“ tan”,“ ate”,“ nat”,“ bat”],返回: [[“ ate”,“ eat”,“ tea”],[“ nat”,“ tan”],[“ bat”]] 3 | 4 | 注意:所有输入均使用小写字母。 -------------------------------------------------------------------------------- /050开方函数实现/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def myPow(self, x, n): 3 | """ 4 | :type x: float 5 | :type n: int 6 | :rtype: float 7 | """ 8 | if n < 0: 9 | n = -n 10 | x = 1 / x 11 | ans = 1 12 | while n: 13 | if n & 1: #n%2 ==1 14 | ans *= x 15 | x *= x 16 | n >>= 1 17 | return ans -------------------------------------------------------------------------------- /050开方函数实现/Question: -------------------------------------------------------------------------------- 1 | 实现pow(x,n)。 -------------------------------------------------------------------------------- /051n皇后/Answer: -------------------------------------------------------------------------------- 1 | n皇后难题是将n个皇后放在n×n棋盘上的问题,这样就不会有两个皇后互相攻击。 2 | 给定整数n,将所有不同的解决方案返回给n-皇后难题。 3 | 每个解决方案都包含一个独特的n-queens有边缘图,其中“ Q”和“。”。 4 | 都分别表示皇后和空白。 5 | 例如,对于四皇后难题有两种不同的解决方案: 6 | [[“ .Q ..”,//解决方案1“ ... Q”,“ Q ...”,“ ..Q。”], 7 | [“ ..Q。”,//解决方案2“ Q ...”,“ ... Q”,“ .Q ..”]] -------------------------------------------------------------------------------- /051n皇后/Question.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def solveNQueens(self, n): 3 | """ 4 | :type n: int 5 | :rtype: List[List[str]] 6 | """ 7 | ans = [] 8 | 9 | def dfs(path, n, ans): 10 | if len(path) == n: 11 | ans.append(drawChess(path)) 12 | return 13 | 14 | for i in range(n): 15 | if i not in path and isValidQueen(path, i): 16 | path.append(i) 17 | dfs(path, n, ans) 18 | path.pop() 19 | 20 | def isValidQueen(path, k): 21 | for i in range(len(path)): 22 | if abs(k - path[i]) == abs(len(path) - i): 23 | return False 24 | return True 25 | 26 | def drawChess(path): 27 | ret = [] 28 | chess = [["."] * len(path) for _ in range(len(path))] 29 | for i in range(0, len(path)): 30 | chess[i][path[i]] = "Q" 31 | for chs in chess: 32 | ret.append("".join(chs)) 33 | return ret 34 | 35 | dfs([], n, ans) 36 | return ans -------------------------------------------------------------------------------- /052n皇后2/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def totalNQueens(self, n): 3 | """ 4 | :type n: int 5 | :rtype: int 6 | """ 7 | 8 | def dfs(path, n): 9 | if len(path) == n: 10 | return 1 11 | res = 0 12 | for i in range(n): 13 | if i not in path and isValidQueen(path, i): 14 | path.append(i) 15 | res += dfs(path, n) 16 | path.pop() 17 | return res 18 | 19 | def isValidQueen(path, k): 20 | for i in range(len(path)): 21 | if abs(k - path[i]) == abs(len(path) - i): 22 | return False 23 | return True 24 | 25 | return dfs([], n) -------------------------------------------------------------------------------- /052n皇后2/Question: -------------------------------------------------------------------------------- 1 | 跟进N皇后问题。 现在,代替输出有边缘图,返回不同解决方案的总数。 -------------------------------------------------------------------------------- /053最大子数组/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def maxSubArray(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: int 6 | """ 7 | if len(nums) == 0: 8 | return 0 9 | preSum = maxSum = nums[0] 10 | for i in range(1, len(nums)): 11 | preSum = max(preSum + nums[i], nums[i]) 12 | maxSum = max(maxSum, preSum) 13 | return maxSum -------------------------------------------------------------------------------- /053最大子数组/Question: -------------------------------------------------------------------------------- 1 | 在总和最大的数组(包含至少一个数字)中找到连续的子数组。 2 | 例如,给定数组[-2,1,-3,4,-1,2,1,-5,4],连续子数组[4,-1,2,1]的最大和= 6。 3 | 4 | 如果您已经找到O(n)解决方案,请尝试使用分治的方法对另一种解决方案进行编码,这种方法更加巧妙。 -------------------------------------------------------------------------------- /054螺旋矩阵/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def spiralOrder(self, matrix): 3 | """ 4 | :type matrix: List[List[int]] 5 | :rtype: List[int] 6 | """ 7 | if len(matrix) == 0 or len(matrix[0]) == 0: 8 | return [] 9 | ans = [] 10 | left, up, down, right = 0, 0, len(matrix) - 1, len(matrix[0]) - 1 11 | while left <= right and up <= down: 12 | for i in range(left, right + 1): 13 | ans += matrix[up][i], 14 | up += 1 15 | for i in range(up, down + 1): 16 | ans += matrix[i][right], 17 | right -= 1 18 | for i in reversed(range(left, right + 1)): 19 | ans += matrix[down][i], 20 | down -= 1 21 | for i in reversed(range(up, down + 1)): 22 | ans += matrix[i][left], 23 | left += 1 24 | return ans[:(len(matrix) * len(matrix[0]))] -------------------------------------------------------------------------------- /054螺旋矩阵/Question: -------------------------------------------------------------------------------- 1 | 给定一个m x n元素的矩阵(m行,n列),以螺旋顺序返回矩阵的所有元素。 2 | 例如,给定以下矩阵: 3 | [[1,2,3], 4 | [4,5,6], 5 | [7,8,9]] 6 | 您应该返回[1,2,3,6,9,8,7,4,5]。 -------------------------------------------------------------------------------- /055跳跃游戏/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def canJump(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: int 6 | """ 7 | pos = 0 8 | bound = len(nums) 9 | while pos < len(nums) - 1: 10 | dis = nums[pos] 11 | if dis == 0: 12 | return False 13 | farthest = posToFarthest = 0 14 | for i in range(pos + 1, min(pos + dis + 1, bound)): 15 | canReach = i + nums[i] 16 | if i == len(nums) - 1: 17 | return True 18 | if canReach > farthest: 19 | farthest = canReach 20 | posToFarthest = i 21 | pos = posToFarthest 22 | return True if pos >= len(nums) - 1 else False -------------------------------------------------------------------------------- /055跳跃游戏/Question: -------------------------------------------------------------------------------- 1 | 给定一个非负整数数组,您最初位于该数组的第一个索引处。 2 | 数组中的每个元素代表该位置的最大跳转长度。 3 | 确定您是否能够达到最后一个索引。 4 | 例如:A = [2,3,1,1,4],返回true。 5 | A = [3,2,1,0,4],返回false。 -------------------------------------------------------------------------------- /056合并间隔/Answer.py: -------------------------------------------------------------------------------- 1 | # Definition for an interval. 2 | # class Interval(object): 3 | # def __init__(self, s=0, e=0): 4 | # self.start = s 5 | # self.end = e 6 | 7 | class Solution(object): 8 | def merge(self, intervals): 9 | """ 10 | :type intervals: List[Interval] 11 | :rtype: List[Interval] 12 | """ 13 | ans = [] 14 | for intv in sorted(intervals, key=lambda x: x.start): 15 | if ans and ans[-1].end >= intv.start: 16 | ans[-1].end = max(ans[-1].end, intv.end) 17 | else: 18 | ans.append(intv) 19 | return ans -------------------------------------------------------------------------------- /056合并间隔/Question: -------------------------------------------------------------------------------- 1 | 给定间隔的集合,合并所有重叠的间隔。 2 | 例如,给定[1,3],[2,6],[8,10],[15,18],返回[1,6],[8,10],[15,18]。 -------------------------------------------------------------------------------- /057插入间隔/Answer.py: -------------------------------------------------------------------------------- 1 | # Definition for an interval. 2 | # class Interval(object): 3 | # def __init__(self, s=0, e=0): 4 | # self.start = s 5 | # self.end = e 6 | 7 | class Solution(object): 8 | def insert(self, intervals, newInterval): 9 | """ 10 | :type intervals: List[Interval] 11 | :type newInterval: Interval 12 | :rtype: List[Interval] 13 | """ 14 | s, e = newInterval.start, newInterval.end 15 | left = filter(lambda x: x.end < newInterval.start, intervals) 16 | right = filter(lambda x: x.start > newInterval.end, intervals) 17 | if left + right != intervals: 18 | s = min(intervals[len(left)].start, s) 19 | e = max(intervals[~len(right)].end, e) 20 | return left + [Interval(s, e)] + right -------------------------------------------------------------------------------- /057插入间隔/Question: -------------------------------------------------------------------------------- 1 | 给定一组不重叠的间隔,请在间隔中插入一个新间隔(必要时合并)。 2 | 您可以假设间隔最初是根据其开始时间排序的。 3 | 示例1:给定间隔[1,3],[6,9],将[2,5]插入并合并为[1,5],[6,9]。示例2:给出[1,2],[3,5],[6,7],[8,10],[12,16],将[4,9]插入并合并为[1,2],[3,10],[12,16]。 4 | 这是因为新间隔[4,9]与[3,5],[6,7],[8,10]重叠。 -------------------------------------------------------------------------------- /058字长/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def lengthOfLastWord(self, s): 3 | """ 4 | :type s: str 5 | :rtype: int 6 | """ 7 | if len(s) == 0: 8 | return 0 9 | s = s.split() 10 | if len(s) > 0: 11 | return len(s[-1]) 12 | return 0 -------------------------------------------------------------------------------- /058字长/Question: -------------------------------------------------------------------------------- 1 | 给定字符串s由大写/小写字母和空格字符''组成,则返回字符串中最后一个单词的长度。 2 | 如果最后一个单词不存在,则返回0。注意:单词被定义为字符序列,仅由非空格字符组成。例如,给定s =“ Hello World”,返回5。 -------------------------------------------------------------------------------- /059螺旋矩阵/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def generateMatrix(self, n): 3 | """ 4 | :type n: int 5 | :rtype: List[List[int]] 6 | """ 7 | ans = [[0] * n for _ in range(n)] 8 | left, right, up, down = 0, n - 1, 0, n - 1 9 | k = 1 10 | while left <= right and up <= down: 11 | for i in range(left, right + 1): 12 | ans[up][i] = k 13 | k += 1 14 | up += 1 15 | for i in range(up, down + 1): 16 | ans[i][right] = k 17 | k += 1 18 | right -= 1 19 | for i in reversed(range(left, right + 1)): 20 | ans[down][i] = k 21 | k += 1 22 | down -= 1 23 | for i in reversed(range(up, down + 1)): 24 | ans[i][left] = k 25 | k += 1 26 | left += 1 27 | return ans -------------------------------------------------------------------------------- /059螺旋矩阵/Question: -------------------------------------------------------------------------------- 1 | 给定一个整数n,生成一个正方形矩阵,该矩阵以螺旋顺序填充从1到n2的元素。 2 | 例如, 3 | 给定n = 3, 4 | 您应该返回以下矩阵: 5 | [ 6 | [1,2,3], 7 | [8,9,4], 8 | [7,6,5] 9 | ] -------------------------------------------------------------------------------- /060排列顺序/Answer.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | 4 | class Solution(object): 5 | def getPermutation(self, n, k): 6 | """ 7 | :type n: int 8 | :type k: int 9 | :rtype: str 10 | """ 11 | visited = [0 for i in range(n)] 12 | fact = [math.factorial(n - i - 1) for i in range(n)] 13 | ans = "" 14 | k -= 1 15 | for i in range(n): 16 | t = k / fact[i] 17 | for j in range(n): 18 | if not visited[j]: 19 | if t == 0: 20 | break 21 | t -= 1 22 | ans += str(j + 1) 23 | k %= fact[i] 24 | visited[j] = 1 25 | return ans -------------------------------------------------------------------------------- /060排列顺序/Question: -------------------------------------------------------------------------------- 1 | 集合[1,2,3,…,n]总共包含n!独特的排列。 2 | 通过按顺序列出和标记所有排列,我们得到以下序列(即,对于n = 3): 3 | “ 123” “ 132” “ 213” “ 231” “ 312” “ 321” 4 | 给定n和k,返回第k个排列序列。 5 | 注意:给定的n将在1到9之间(含1和9)。 -------------------------------------------------------------------------------- /061旋转列表/Answer.py: -------------------------------------------------------------------------------- 1 | # 定义一个单链表 2 | # class ListNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.next = None 6 | 7 | class Solution(object): 8 | def rotateRight(self, head, k): 9 | """ 10 | :type head: ListNode 11 | :type k: int 12 | :rtype: ListNode 13 | """ 14 | if not head: 15 | return head 16 | l = 1 17 | p = head 18 | while p.next: 19 | l += 1 20 | p = p.next 21 | k = k % l 22 | if k == 0: 23 | return head 24 | k = l - k % l - 1 25 | pp = head 26 | print 27 | k 28 | while k > 0: 29 | pp = pp.next 30 | k -= 1 31 | newHead = pp.next 32 | pp.next = None 33 | p.next = head 34 | return newHead -------------------------------------------------------------------------------- /061旋转列表/Question: -------------------------------------------------------------------------------- 1 | 给定一个列表,将列表向右旋转k个位置,其中k为非负数。 2 | 例如:给定1-> 2-> 3-> 4-> 5-> NULL且k = 2,则返回4-> 5-> 1-> 2-> 3-> NULL。 -------------------------------------------------------------------------------- /062唯一路径/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def uniquePaths(self, m, n): 3 | """ 4 | :type m: int 5 | :type n: int 6 | :rtype: int 7 | """ 8 | dp = [1] * n 9 | 10 | for i in range(1, m): 11 | pre = 1 12 | for j in range(1, n): 13 | dp[j] = dp[j] + pre 14 | pre = dp[j] 15 | return dp[-1] -------------------------------------------------------------------------------- /062唯一路径/Question: -------------------------------------------------------------------------------- 1 | 机械手位于m x n网格的左上角(在下图中标记为“开始”)。 2 | 机器人只能在任何时间点上下移动。机器人试图到达网格的右下角(在下图中标记为“完成”)。 3 | 有多少种可能的独特路径? 4 | 上面是一个3 x 7的网格。有多少种可能的独特路径? 5 | 注意:m和n最多为100。 -------------------------------------------------------------------------------- /063唯一路径2/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def uniquePathsWithObstacles(self, grid): 3 | """ 4 | :type obstacleGrid: List[List[int]] 5 | :rtype: int 6 | """ 7 | if not grid: 8 | return 0 9 | if grid[0][0] == 1: 10 | return 0 11 | dp = [[0] * len(grid[0]) for _ in range(0, len(grid))] 12 | dp[0][0] = 1 if grid[0][0] == 0 else 0 13 | for i in range(1, len(grid)): 14 | if grid[i][0] == 0: 15 | dp[i][0] = 1 16 | else: 17 | break 18 | 19 | for j in range(1, len(grid[0])): 20 | if grid[0][j] == 0: 21 | dp[0][j] = 1 22 | else: 23 | break 24 | 25 | for i in range(1, len(grid)): 26 | for j in range(1, len(grid[0])): 27 | if grid[i][j] == 1: 28 | dp[i][j] = 0 29 | else: 30 | dp[i][j] = dp[i - 1][j] + dp[i][j - 1] 31 | return dp[-1][-1] -------------------------------------------------------------------------------- /063唯一路径2/Question: -------------------------------------------------------------------------------- 1 | 接着上一个题目 “唯一路径”: 2 | 现在考虑在网格中添加一些障碍。会有多少条不同的路径? 3 | 障碍物和空白区域在网格中分别标记为1和0。 4 | 例如,如下图所示,在3x3网格中间有一个障碍物。 5 | [[0,0,0],[0,1,0],[0,0,0]] 6 | 唯一路径的总数为2。 7 | 注意:m和n最多为100。 -------------------------------------------------------------------------------- /064最小路径总和/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def minPathSum(self, grid): 3 | """ 4 | :type grid: List[List[int]] 5 | :rtype: int 6 | """ 7 | if len(grid) == 0: 8 | return 0 9 | dp = [0 for _ in range(0, len(grid[0]))] 10 | dp[0] = grid[0][0] 11 | 12 | for j in range(1, len(grid[0])): 13 | dp[j] = dp[j - 1] + grid[0][j] 14 | 15 | for i in range(1, len(grid)): 16 | pre = dp[0] + grid[i][0] 17 | for j in range(1, len(grid[0])): 18 | dp[j] = min(dp[j], pre) + grid[i][j] 19 | pre = dp[j] 20 | dp[0] += grid[i][0] 21 | 22 | return dp[-1] -------------------------------------------------------------------------------- /064最小路径总和/Question: -------------------------------------------------------------------------------- 1 | 看到题目就想到了DP 2 | 3 | 给定一个m×n的网格,其中填充了非负数,请找到一条从左上到右下的路径,该路径将沿其路径的所有数字的总和最小化。 4 | 注意:您只能在任何时间点向下或向右移动。 5 | 6 | -------------------------------------------------------------------------------- /065有效号码/Answer.py: -------------------------------------------------------------------------------- 1 | class States(object): 2 | def __init__(self): 3 | self.init = 0 4 | self.decimal = 1 5 | self.decpoint = 2 6 | self.afterdp = 3 7 | self.e = 4 8 | self.aftere = 5 9 | self.sign = 6 10 | self.nullpoint = 7 11 | self.esign = 8 12 | self.afteresign = 9 13 | 14 | 15 | class Solution(object): 16 | def isNumber(self, s): 17 | """ 18 | :type s: str 19 | :rtype: bool 20 | """ 21 | s = s.strip() 22 | states = States() 23 | state = states.init 24 | decimals = "01234567890" 25 | 26 | for c in s: 27 | if state == states.init: 28 | if c == ".": 29 | state = states.nullpoint 30 | elif c in decimals: 31 | state = states.decimal 32 | elif c in ["+", "-"]: 33 | state = states.sign 34 | else: 35 | return False 36 | elif state == states.sign: 37 | if c in decimals: 38 | state = states.decimal 39 | elif c == ".": 40 | state = states.nullpoint 41 | else: 42 | return False 43 | elif state == states.esign: 44 | if c not in decimals: 45 | return False 46 | state = states.afteresign 47 | elif state == states.afteresign: 48 | if c not in decimals: 49 | return False 50 | elif state == states.nullpoint: 51 | if c not in decimals: 52 | return False 53 | state = states.decpoint 54 | elif state == states.decimal: 55 | if c in decimals: 56 | continue 57 | elif c == "e": 58 | state = states.e 59 | elif c == ".": 60 | state = states.decpoint 61 | else: 62 | return False 63 | elif state == states.decpoint: 64 | if c in decimals: 65 | state = states.afterdp 66 | elif c == "e": 67 | state = states.e 68 | else: 69 | return False 70 | elif state == states.afterdp: 71 | if c in decimals: 72 | continue 73 | elif c == "e": 74 | state = states.e 75 | else: 76 | return False 77 | elif state == states.e: 78 | if c in decimals: 79 | state = states.aftere 80 | elif c in ["+", "-"]: 81 | state = states.esign 82 | else: 83 | return False 84 | elif state == states.aftere: 85 | if c not in decimals: 86 | return False 87 | else: 88 | return False 89 | return state not in [states.init, states.e, states.nullpoint, states.sign, states.esign] -------------------------------------------------------------------------------- /065有效号码/Question: -------------------------------------------------------------------------------- 1 | 验证给定的字符串是否为数字。 2 | 一些示例:“ 0” => true“ 0.1” => true“ abc” => false“ 1 a” => false“ 2e10” => true 3 | 注意:问题陈述的意图是模棱两可的。在实施一项之前,您应该先收集所有需求。 4 | 更新(2015-02-10):C ++函数的签名已更新。如果仍然看到函数签名接受const char *参数,请单击重新加载按钮以重置代码定义。 -------------------------------------------------------------------------------- /066加一/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def plusOne(self, digits): 3 | """ 4 | :type digits: List[int] 5 | :rtype: List[int] 6 | """ 7 | carry = 1 8 | for i in reversed(range(0, len(digits))): 9 | digit = (digits[i] + carry) % 10 10 | carry = 1 if digit < digits[i] else 0 11 | digits[i] = digit 12 | if carry == 1: 13 | return [1] + digits 14 | return digits -------------------------------------------------------------------------------- /066加一/Question: -------------------------------------------------------------------------------- 1 | 给定一个表示为非空数字数组的非负整数,该整数加1。 2 | 您可以假定该整数不包含任何前导零,数字0本身除外。 3 | 这些数字的存储方式是使最高有效数字位于列表的开头。 -------------------------------------------------------------------------------- /067二进制加法/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def addBinary(self, a, b): 3 | """ 4 | :type a: str 5 | :type b: str 6 | :rtype: str 7 | """ 8 | diff = abs(len(a) - len(b)) 9 | if len(a) > len(b): 10 | b = "0" * diff + b 11 | else: 12 | a = "0" * diff + a 13 | 14 | ret = "" 15 | carry = 0 16 | ai, bi = len(a) - 1, len(b) - 1 17 | al, bl = len(a), len(b) 18 | while ai >= 0 and bi >= 0: 19 | ac, bc = a[ai], b[bi] 20 | if ac == "1" and bc == "1": 21 | if carry == 1: 22 | ret += "1" 23 | else: 24 | ret += "0" 25 | carry = 1 26 | elif ac == "0" and bc == "0": 27 | if carry == 1: 28 | ret += "1" 29 | else: 30 | ret += "0" 31 | carry = 0 32 | else: 33 | if carry == 1: 34 | ret += "0" 35 | else: 36 | ret += "1" 37 | 38 | ai -= 1 39 | bi -= 1 40 | 41 | if carry == 1: 42 | ret += "1" 43 | return ret[::-1] -------------------------------------------------------------------------------- /067二进制加法/Question: -------------------------------------------------------------------------------- 1 | 给定两个二进制字符串,返回它们的总和(也是一个二进制字符串)。 2 | 3 | 例如,a =“ 11” b =“ 1”返回“ 100”。 -------------------------------------------------------------------------------- /068文本对齐/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def fullJustify(self, words, maxWidth): 3 | """ 4 | :type words: List[str] 5 | :type maxWidth: int 6 | :rtype: List[str] 7 | """ 8 | ans = [] 9 | line = [] 10 | lens = map(len, words) 11 | idx = 0 12 | curLen = 0 13 | while idx < len(words): 14 | if curLen == 0: 15 | curLen = lens[idx] 16 | else: 17 | curLen += lens[idx] + 1 18 | line.append(words[idx]) 19 | idx += 1 20 | if curLen > maxWidth: 21 | curLen = 0 22 | line.pop() 23 | idx -= 1 24 | if len(line) == 1: 25 | ans.append(line[0] + " " * (maxWidth - len(line[0]))) 26 | line = [] 27 | continue 28 | spaces = maxWidth - sum(map(len, line)) 29 | avgSpace = spaces / (len(line) - 1) 30 | extraSpace = spaces % (len(line) - 1) 31 | res = "" 32 | for i in range(0, len(line)): 33 | res += line[i] 34 | if i < len(line) - 1: 35 | res += " " * (avgSpace + (extraSpace > 0)) 36 | extraSpace -= 1 37 | ans.append(res) 38 | line = [] 39 | elif idx == len(words): 40 | res = "" 41 | for i in range(0, len(line)): 42 | res += line[i] 43 | if i < len(line) - 1: 44 | res += " " 45 | res += " " * (maxWidth - len(res)) 46 | ans.append(res) 47 | return ans -------------------------------------------------------------------------------- /068文本对齐/Question: -------------------------------------------------------------------------------- 1 | 给定一个单词数组和一个长度L,请格式化文本,以使每一行都具有L个字符,并且完全(左右)对齐。 2 | 3 | 您应该用一种贪婪的方式包装;也就是说,在每一行中尽可能多地打包单词。如有必要,请在空格处加上多余的空格'',以使每行都具有L个字符。 4 | 5 | 单词之间的多余空间应尽可能均匀地分布。如果一行中的空格数量在单词之间没有平均分配,则左侧的空插槽将比右侧的插槽分配更多的空间。 6 | 7 | 文本的最后一行,应保留其两端对齐,并且单词之间不应插入多余的空格。 8 | 9 | 例如:单词:["This", "is", "an", "example", "of", "text", "justification."] L: 16. 10 | 11 | 将格式化的行返回为: 12 | 13 | [ "This is an", "example of text", "justification. " ] 14 | 15 | 注意:保证每个单词的长度不超过L。 16 | 17 | 18 | 19 | 边界案例: 20 | 21 | 最后一行以外的其他行可能仅包含一个单词。在这种情况下该怎么办?在这种情况下,该行应左对齐。 -------------------------------------------------------------------------------- /069平方根实现/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def mySqrt(self, x): 3 | """ 4 | :type x: int 5 | :rtype: int 6 | """ 7 | lo = 0 8 | hi = x 9 | while lo <= hi: 10 | mid = (hi + lo) // 2 11 | v = mid * mid 12 | if v < x: 13 | lo = mid + 1 14 | elif v > x: 15 | hi = mid - 1 16 | else: 17 | return mid 18 | return hi -------------------------------------------------------------------------------- /069平方根实现/Question: -------------------------------------------------------------------------------- 1 | 实现int sqrt(int x函数。 2 | 计算并返回x的平方根。 -------------------------------------------------------------------------------- /070爬楼梯/Answer.py: -------------------------------------------------------------------------------- 1 | 最先开始想到的 2 | class Solution: 3 | def climbStairs(self, n): 4 | """ 5 | :type n: int 6 | :rtype: int 7 | """ 8 | return 1 if n == 0 or n == 1 else self.climbStairs(n - 1) + self.climbStairs(n - 2) 9 | # 超时了,意料之中 10 | 11 | 12 | #然后DP 13 | 14 | class Solution: 15 | def climbStairs(self, n): 16 | """ 17 | :type n: int 18 | :rtype: int 19 | """ 20 | climb = dict() 21 | climb[0], climb[1] = 1, 1 22 | for i in range(2, n + 1): 23 | climb[i] = climb[i - 1] + climb[i- 2] 24 | return climb[n] 25 | 26 | 27 | #实际上这个问题是斐波那契数列的变形 28 | 29 | class Solution(object): 30 | def climbStairs(self, n): 31 | """ 32 | :type n: int 33 | :rtype: int 34 | """ 35 | if n <= 1: 36 | return 1 37 | pre, ppre = 1, 1 38 | for i in range(2, n + 1): 39 | tmp = pre 40 | pre = ppre + pre 41 | ppre = tmp 42 | return pre -------------------------------------------------------------------------------- /070爬楼梯/Question: -------------------------------------------------------------------------------- 1 | 您正在爬楼梯。它需要n步才能到达顶部。 2 | 每次您可以爬1或2步。您可以通过几种不同的方式登顶? 注意:给定n将为正整数。 -------------------------------------------------------------------------------- /071简单路径/Answer: -------------------------------------------------------------------------------- 1 | 给定文件的绝对路径(Unix风格),简化它。 2 | 例如,path=“/home/“,=>“/home“路径=“/a/./b/../c/“,=>“/c“ 3 | 单击以显示角箱。 4 | 角落案例: 5 | 你考虑过path=“/../“的情况吗?在这种情况下,您应该返回“/”。 6 | 另一种情况是路径可能包含多个斜杠“/”,例如“/home//foo/”。 7 | 在这种情况下,应该忽略多馀的斜杠并返回“/home/foo”。 -------------------------------------------------------------------------------- /071简单路径/Question.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def simplifyPath(self, path): 3 | """ 4 | :type path: str 5 | :rtype: str 6 | """ 7 | path = path.split("/") 8 | stack = [] 9 | for p in path: 10 | if p in ["", "."]: 11 | continue 12 | if p == "..": 13 | if stack: 14 | stack.pop() 15 | else: 16 | stack.append(p) 17 | return "/" + "/".join(stack) -------------------------------------------------------------------------------- /072编辑距离/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def minDistance(self, word1, word2): 3 | """ 4 | :type word1: str 5 | :type word2: str 6 | :rtype: int 7 | """ 8 | if len(word1) == 0 or len(word2) == 0: 9 | return max(len(word1), len(word2)) 10 | 11 | dp = [[0] * (len(word2) + 1) for _ in range(0, len(word1) + 1)] 12 | dp[0][0] = 0 13 | 14 | for i in range(0, len(word1) + 1): 15 | for j in range(0, len(word2) + 1): 16 | if i == 0: 17 | dp[i][j] = j 18 | elif j == 0: 19 | dp[i][j] = i 20 | else: 21 | cond1 = dp[i][j - 1] + 1 22 | cond2 = dp[i - 1][j] + 1 23 | cond3 = 0 24 | if word1[i - 1] == word2[j - 1]: 25 | cond3 = dp[i - 1][j - 1] 26 | else: 27 | cond3 = dp[i - 1][j - 1] + 1 28 | dp[i][j] = min(cond1, cond2, cond3) 29 | return dp[-1][-1] -------------------------------------------------------------------------------- /072编辑距离/Question: -------------------------------------------------------------------------------- 1 | 给定两个单词word1和word2,找出将word1转换为word2所需的最小步骤数。(每个操作计算为1步。) 2 | 你有以下3个操作允许一个字: 3 | A)插入字符b)删除字符c)替换字符 -------------------------------------------------------------------------------- /073设置矩阵零/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def setZeroes(self, matrix): 3 | """ 4 | :type matrix: List[List[int]] 5 | :rtype: void Do not return anything, modify matrix in-place instead. 6 | """ 7 | colZeroFlag = False 8 | for i in range(0, len(matrix)): 9 | if matrix[i][0] == 0: 10 | colZeroFlag = True 11 | for j in range(1, len(matrix[0])): 12 | if matrix[i][j] == 0: 13 | matrix[i][0] = matrix[0][j] = 0 14 | 15 | for i in reversed(range(0, len(matrix))): 16 | for j in reversed(range(1, len(matrix[0]))): 17 | if matrix[i][0] == 0 or matrix[0][j] == 0: 18 | matrix[i][j] = 0 19 | if colZeroFlag: 20 | matrix[i][0] = 0 -------------------------------------------------------------------------------- /073设置矩阵零/Question: -------------------------------------------------------------------------------- 1 | 给定一个m×n矩阵,如果一个元素是0,设置它的整个行和列为0。 2 | 3 | 后续: 4 | 你用了额外的空间吗?使用O(mn)空间的直接的解决方案可能是一个坏主意。 5 | 一个简单的改进使用了O(m+n)空间,但仍然不是最好的解决方案。你能想出一个恒定的空间解吗? -------------------------------------------------------------------------------- /074搜索一个二维矩阵/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def searchMatrix(self, matrix, target): 3 | """ 4 | :type matrix: List[List[int]] 5 | :type target: int 6 | :rtype: bool 7 | """ 8 | if len(matrix) == 0 or len(matrix[0]) == 0: 9 | return False 10 | 11 | m = len(matrix) 12 | n = len(matrix[0]) 13 | 14 | start, end = 0, m * n - 1 15 | while start + 1 < end: 16 | mid = start + (end - start) / 2 17 | if matrix[mid / n][mid % n] > target: 18 | end = mid 19 | elif matrix[mid / n][mid % n] < target: 20 | start = mid 21 | else: 22 | return True 23 | if matrix[start / n][start % n] == target: 24 | return True 25 | if matrix[end / n][end % n] == target: 26 | return True 27 | return False -------------------------------------------------------------------------------- /074搜索一个二维矩阵/Question: -------------------------------------------------------------------------------- 1 | 编写一个高效的算法,在一个m×n矩阵中搜索一个值。该矩阵具有以下特性: 2 | 每行中的整数从左到右排序。每行的第一个整数大于前一行的最后一个整数。 3 | 比如, 4 | 考虑以下矩阵: 5 | [ 6 | [1, 3, 5, 7], 7 | [10, 11, 16, 20], 8 | [23, 30, 34, 50] 9 | ] 10 | 给定目标=3,返回true。 -------------------------------------------------------------------------------- /075颜色排序/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def sortColors(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: void Do not return anything, modify nums in-place instead. 6 | """ 7 | x = y = z = -1 8 | for i in range(0, len(nums)): 9 | if nums[i] == 0: 10 | x += 1 11 | y += 1 12 | z += 1 13 | if z != -1: 14 | nums[z] = 2 15 | if y != -1: 16 | nums[y] = 1 17 | nums[x] = 0 18 | elif nums[i] == 1: 19 | y += 1 20 | z += 1 21 | nums[z] = 2 22 | if x != -1: 23 | nums[x] = 0 24 | if y != -1: 25 | nums[y] = 1 26 | elif nums[i] == 2: 27 | z += 1 28 | if y != -1: 29 | nums[y] = 1 30 | if x != -1: 31 | nums[x] = 0 32 | nums[z] = 2 -------------------------------------------------------------------------------- /075颜色排序/Question: -------------------------------------------------------------------------------- 1 | 给定一个数组,其中包含n个颜色分别为红色,白色或蓝色的对象,请对其进行排序,以使相同颜色的对象相邻,颜色顺序为红色,白色和蓝色。 2 | 3 | 在这里,我们将使用整数0、1和2分别代表红色,白色和蓝色。 4 | 5 | 注意:您不应使用该库的sort函数来解决此问题。 6 | 7 | 8 | 9 | Tips:一个比较简单的解决方案是使用计数排序的两次通过算法。 首先,迭代计数为0、1和2的数组,然后覆盖总数为0,然后为1和2的数组。 您能提出一种仅使用恒定空间的单遍算法吗? -------------------------------------------------------------------------------- /076最小窗口子串/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def minWindow(self, s, t): 3 | """ 4 | :type s: str 5 | :type t: str 6 | :rtype: str 7 | """ 8 | score = 0 9 | wanted = collections.Counter(t) 10 | start, end = len(s), 3 * len(s) 11 | d = {} 12 | deq = collections.deque([]) 13 | for i, c in enumerate(s): 14 | if c in wanted: 15 | deq.append(i) 16 | d[c] = d.get(c, 0) + 1 17 | if d[c] <= wanted[c]: 18 | score += 1 19 | while deq and d[s[deq[0]]] > wanted[s[deq[0]]]: 20 | d[s[deq.popleft()]] -= 1 21 | if score == len(t) and deq[-1] - deq[0] < end - start: 22 | start, end = deq[0], deq[-1] 23 | return s[start:end + 1] -------------------------------------------------------------------------------- /076最小窗口子串/Question: -------------------------------------------------------------------------------- 1 | 给定一个字符串S和一个字符串T,找到S中的最小窗口,该窗口将包含复杂度为O(n)的T中的所有字符。 2 | 例如,S=“ADOBECODEBANC” T=“ABC” 3 | 最小窗口为“BANC”。(即边界为T中的字符的最短子串,且覆盖了T) 4 | 注意:如果S中没有覆盖T中所有字符的窗口,则返回空字符串“”。 5 | 如果有多个这样的窗口,则保证在S中始终只有一个唯一的最小窗口。 -------------------------------------------------------------------------------- /077组合/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def combine(self, n, k): 3 | if k == 1: 4 | return [[i] for i in range(1, n + 1)] 5 | elif k == n: 6 | return [[i for i in range(1, n + 1)]] 7 | else: 8 | rs = [] 9 | rs += self.combine(n - 1, k) 10 | part = self.combine(n - 1, k - 1) 11 | for ls in part: 12 | ls.append(n) 13 | rs += part 14 | return rs -------------------------------------------------------------------------------- /077组合/Question: -------------------------------------------------------------------------------- 1 | 给定两个整数n和k,返回1 ... n中k个数字的所有可能组合。 2 | 例如,如果n = 4且k = 2,则解为: [[2,4],[3,4],[2,3],[1,2],[1,3],[1,4],] -------------------------------------------------------------------------------- /078子集/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def subsets(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: List[List[int]] 6 | """ 7 | 8 | def dfs(nums, index, path, ans): 9 | ans.append(path) 10 | [dfs(nums, i + 1, path + [nums[i]], ans) for i in range(index, len(nums))] 11 | 12 | ans = [] 13 | dfs(nums, 0, [], ans) 14 | return ans -------------------------------------------------------------------------------- /078子集/Question: -------------------------------------------------------------------------------- 1 | 给定一组不同的整数nums,返回所有可能的子集。 2 | 注意:解决方案集不得包含重复的子集。 3 | 例如,如果nums = [1,2,3],则解决方案是: 4 | 5 | [[1],[2],[3],[1,2,3],[1,3],[2,3],[1,2],[]] -------------------------------------------------------------------------------- /079单词搜索/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param board, a list of lists of 1 length string 3 | # @param word, a string 4 | # @return a boolean 5 | def exist(self, board, word): 6 | # write your code here 7 | if word == "": 8 | return True 9 | if len(board) == 0: 10 | return False 11 | visited = [[0] * len(board[0]) for i in range(0, len(board))] 12 | directions = [(-1, 0), (1, 0), (0, -1), (0, 1)] 13 | 14 | def dfs(i, j, board, visited, word, index): 15 | if word[index] != board[i][j]: 16 | return False 17 | if len(word) - 1 == index: 18 | return True 19 | for direction in directions: 20 | ni, nj = i + direction[0], j + direction[1] 21 | if ni >= 0 and ni < len(board) and nj >= 0 and nj < len(board[0]): 22 | if visited[ni][nj] == 0: 23 | visited[ni][nj] = 1 24 | if dfs(ni, nj, board, visited, word, index + 1): 25 | return True 26 | visited[ni][nj] = 0 27 | return False 28 | 29 | for i in range(0, len(board)): 30 | for j in range(0, len(board[0])): 31 | visited[i][j] = 1 32 | if dfs(i, j, board, visited, word, 0): 33 | return True 34 | visited[i][j] = 0 35 | return False -------------------------------------------------------------------------------- /079单词搜索/Question: -------------------------------------------------------------------------------- 1 | 给定一个二维板和一个单词,找出这个单词是否存在于网格中。 2 | 单词可以由顺序相邻单元格的字母组成,其中“相邻”单元格是指水平或垂直相邻的单元格。同一个字母单元格不能多次使用。 3 | 例如,给定的网格= 4 | [ 5 | ['A','B','C','E'], 6 | ['S','F','C','S', 7 | ['A','D','E','E'] 8 | ] 9 | word=“ABCCED”,->返回true,word=“SEE”,->返回true,word=“ABCB”,->返回false。 -------------------------------------------------------------------------------- /080删除排序数组中的重复项/Answer.py: -------------------------------------------------------------------------------- 1 | class Solution(object): 2 | def removeDuplicates(self, nums): 3 | """ 4 | :type nums: List[int] 5 | :rtype: int 6 | """ 7 | if len(nums) <= 2: 8 | return len(nums) 9 | cnt = 0 10 | j = 1 11 | for i in range(1, len(nums)): 12 | if nums[i] == nums[i - 1]: 13 | cnt += 1 14 | if cnt < 2: 15 | nums[j] = nums[i] 16 | j += 1 17 | else: 18 | nums[j] = nums[i] 19 | j += 1 20 | cnt = 0 21 | return j -------------------------------------------------------------------------------- /080删除排序数组中的重复项/Question: -------------------------------------------------------------------------------- 1 | 如果重复的元素最多允许出现两次怎么办? 2 | 例如,给定排序数组nums=【1,1,1,2,2,3】, 3 | 函数的前五个元素是1、1、2、2和3。在新长度之外,你留下什么并不重要。 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pydatas-leecode 2 | Leecode刷题小队,Python代码实现 3 | --------------------------------------------------------------------------------