每天三道力扣题
leecode 题集
2.给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照
逆序的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class ListNode(object): def __init__(self, x): self.val = x self.next = None class Solution(object): def addTwoNumbers(self, l1, l2): n = ListNode(0) s = 0 node = n while l1 or l2 or s: n.next = ListNode(s + (0 or l1.val if l1 else 0) + (0 or l2.val if l2 else 0)) if n.next.val >= 10: n.next.val -= 10 s = 1 else: s = 0 l1 = l1.next if l1 else None l2 = l2.next if l2 else None n = n.next return node.next
3.给定一个字符串,请你找出其中不含有重复字符的最长子串的长度。
双for循环时间超时
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Solution(object): def lengthOfLongestSubstring(self, s): nums = [] n = '' if not s: return 0 for i in range(len(s)): if s[i] in n: nums.append(len(n)) n = n[n.index(s[i])+1:] n += s[i] if i == len(s)-1: nums.append(len(n)) return max(nums)
4.给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。
请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Solution: def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float: n = nums1 + nums2 n = sorted(n) if len(n) % 2: return n[len(n)//2] else: return (n[len(n)//2]+n[len(n)//2-1])/2
5.给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
动态规划
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Solution: def longestPalindrome(self, s: str) -> str: length = len(s) if length <= 1: return s flag = [[False for i in range(length)] for i in range(length)] longest = 1 ret = s[0] for i in range(length): #tail for j in range(i): #head if s[i] == s[j] and (i - j <= 2 or flag[j+1][i-1]): flag[j][i] = True long = i - j + 1 if long > longest: longest = long ret = s[j: i+1] return ret
6.将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下:
L C I R
E T O E S I I G
E D H N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"。
请你实现这个将字符串进行指定行数变换的函数:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Solution: def convert(self, s: str, numRows: int) -> str: size = len(s) if numRows == 1: return s yilun = 2*numRows - 2 l = [[] for _ in range(numRows)] for i in range(size): num = i % yilun if num > numRows - 1: l[2*numRows-2-num].append(s[i]) else: l[num].append(s[i]) n = '' for i in l: n += ''.join(i) return n
7.给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Solution: def reverse(self, x: int) -> int: if x >= 0: s = str(x)[::-1] else: s = '-' + str(-x)[::-1] s = int(s) if -2 ** 31 < s < 2**31 - 1: return s else: return 0
8.请你来实现一个 atoi 函数,使其能将字符串转换成整数。
首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。
当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字组合起来,作为该整数的正负号;假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成整数。
该字符串除了有效的整数部分之后也可能会存在多余的字符,这些字符可以被忽略,它们对于函数不应该造成影响。
注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换。
在任何情况下,若函数不能进行有效的转换时,请返回 0。
说明:
假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231, 231 − 1]。如果数值超过这个范围,请返回 INT_MAX (231 − 1) 或 INT_MIN (−231) 。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Solution: def myAtoi(self, str: str) -> int: s = str.strip() n = '0123456789' m = '' for i in range(len(s)): if i == 0: if s[i] in n or s[i] in '-+': m += s[i] else: break else: if s[i] in n: m += s[i] else: break if m == '' or m in '-+': return 0 m = int(m) if -2**31 < m < 2**31 - 1: return m else: if m >= 0: return 2**31-1 else: return -2**31
9.判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Solution: def isPalindrome(self, x: int) -> bool: s = str(x) s1 = s[::-1] return s == s1
10.给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。
'.' 匹配任意单个字符
'*' 匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。
说明:
s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *。
动态规划
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Solution: def isMatch(self, s: str, p: str) -> bool: s = '#' + s p = '#' + p m = len(s) n = len(p) dp = [[False for _ in range(n)] for _ in range(m)] dp[0][0] = True for i in range(1, n): if p[i] == '*': dp[0][i] = dp[0][i - 2] for i in range(1, m): for j in range(1, n): if s[i] == p[j]: dp[i][j] = dp[i - 1][j - 1] elif p[j] == '.': dp[i][j] = dp[i - 1][j - 1] elif p[j] == '*': if p[j - 1] == s[i] or p[j - 1] == '.': dp[i][j] = (dp[i][j - 2] or dp[i][j - 1] or dp[i - 1][j]) else: dp[i][j] = dp[i][j - 2] return dp[-1][-1]
11.给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器,且 n 的值至少为 2。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Solution: def maxArea(self, height) -> int: left = 0 right = len(height) - 1 s = 0 while left < right: if height[left] < height[right]: s = max(height[left]*(right - left), s) left += 1 else: s = max(height[right] * (right - left), s) right -= 1 return s
12.罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:
I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个整数,将其转为罗马数字。输入确保在 1 到 3999 的范围内。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Solution: def intToRoman(self, num): rule = { 0: { 1: 'I', 5: 'V', 4: 'IV', 9: 'IX' }, 1: { 1: 'X', 5: 'L', 4: 'XL', 9: 'XC' }, 2: { 1: 'C', 5: 'D', 4: 'CD', 9: 'CM' }, 3: { 1: 'M', } } num_str = str(num)[::-1] size = len(num_str) l = [] for i in range(size): rule_i = rule[i] num_i = int(num_str[i]) if num_i in rule_i: s = rule_i[num_i] elif num_i < 5: s = num_i * rule_i[1] else: s = rule_i[5] + rule_i[1] * (num_i - 5) l.append(s) return ''.join(l[::-1])
14.编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Solution: def longestCommonPrefix(self, strs): if strs: if len(strs) == 1: return strs[0] first = strs[0] size = len(first) l = [] for j in range(size): f = True str1 = first[0:j+1] for n in strs[1:]: if str1 == n[0:j+1]: pass else: f = False break if f: l.append(str1) if l: return max(l, key=len) return ''
15.给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Solution: def threeSum(self, nums): sort_nums = sorted(nums) size = len(nums) se = set() for m in range(size): if m < size - 1: left = m + 1 right = size - 1 sl = sort_nums[left] sr = sort_nums[right] s = sort_nums[m] while left < right: if sl + sr + s > 0: right -= 1 elif sl + sr + s < 0: left += 1 else: se.add((s, sl, sr)) left += 1 sl = sort_nums[left] sr = sort_nums[right] return se