classSolution: defaddTwoNumbers(self, l1, l2): r = re = ListNode(0) # 是否进位 carry = 0 # 当任意一方存在 while l1 or l2: x = l1.val if l1 else0 y = l2.val if l2 else0 s = carry + x + y carry = s // 10 r.next = ListNode(s % 10) r = r.next if l1: l1 = l1.next if l2: l2 = l2.next
classSolution: deflengthOfLongestSubstring(self, s: str) -> int: res = tot = 0 d = {} for idx inrange(len(s)): if s[idx] notin d: d[s[idx]] = idx tot += 1 else: res = max(tot,res) tot = idx - d[s[idx]] d[s[idx]] = idx res = max(tot,res) returnmax(tot,res)
正确代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# idx 表示子串终止位置,i表示字串起始位置 # 当未出现重复时,字符串的长度即为字符串的结束位置减去起始位置。 # 发生重复时,重新利用字符串的结束位置idx减去新的起始位置i,并与之前的未重复字串的长度作比较取较大者 classSolution: deflengthOfLongestSubstring(self, s): d = {} i, res = 0, 0 for idx inrange(len(s)): if s[idx] in d: i = max(d[s[idx]], i) # idx - i + 1就是新子串的长度 res = max(res, idx - i + 1) d[s[idx]] = idx + 1 return res
return longest_palindrome_str # 中心扩散法 def__center_spread(self, s, size, left, right): """ left = right 的时候,此时回文中心是一条线,回文串的长度是奇数 right = left + 1 的时候,此时回文中心是任意一个字符,回文串的长度是偶数 """ l = left r = right
while l >= 0and r < size and s[l] == s[r]: l -= 1 r += 1 return s[l + 1:r], r - l - 1
classSolution: defmaxArea(self, height): res = 0 for idx1 inrange(len(height)): for idx2 inrange(idx1+1,len(height)): res = max(res,(idx2-idx1)*min(height[idx1],height[idx2])) return res
正确的代码是使用动态规划:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
classSolution(object): defmaxArea(self, height): left = 0 right = len(height) - 1 maxArea = 0 while left < right: b = right - left # 左边短就左边移动一根,右边短就右边移动一根. if height[left] < height[right]: h = height[left] left += 1 else: h = height[right] right -= 1 area = b*h if maxArea < area: maxArea = area return maxArea
简化如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
classSolution(object): defmaxArea(self, height): left = 0 right = len(height) - 1 res = 0
while left < right: b = right-left if height[left] < height[right]: h = height[left] left += 1 else: h = height[right] right -= 1 res = max(res,h*b)
classSolution: defthreeSum(self, nums): res = [] nums.sort()
# 遍历到倒数第三即可 for i inrange(len(nums)-2): # 排好序之后,如果nums[i]>0,说明后面的数全部大于0 if nums[i] > 0: break # 去重 if i == 0or nums[i] > nums[i-1]: left,right = i+1,len(nums)-1 # 剪枝 # 如果c及其后面连着两个数a,b,他们的和已经大于0了,就没必要进行下一步的操作 # 同理,如果c和数组最后两个数的和仍然小于0,也没必要进行下一步操作。 if nums[i] + nums[left] + nums[left+1] > 0or nums[i] + nums[right-1] + nums[right] < 0: continue while left < right: ident = nums[i] + nums[left] + nums[right] if ident == 0: res.append([nums[i],nums[left],nums[right]]) left += 1 right -= 1 # 去重,去除连续排列的数字 while left < right and nums[left] == nums[left-1]: left += 1 while left < right and nums[right] == nums[right+1]: right -= 1 elif ident < 0: left += 1 else: right -= 1 return res
for idx inrange(len(nums)-2): left = idx + 1 right = len(nums) - 1
while left < right: count = nums[idx] + nums[left] + nums[right] if count < target: left += 1 elif count > target: right -= 1 else: return count ifabs(count-target) < abs(res-target): res = count
# 优化部分 while left < right and nums[left] == nums[left-1]: left += 1 while left < right and right+1 < len(nums) and nums[right] == nums[right+1]: right -= 1 return res
output = [] for digit in digits_list: iflen(output) == 0: for char in themap[digit]: output.append(char) else: temp = [] for elem in output: for char in themap[digit]: temp.append(elem + char) output += temp
y = lambda x : len(x) == len(digits_list) returnlist(filter(y,output))
classSolution: deffourSum(self, nums, target): res = [] ifnot nums: return res
nums.sort()
for idx1 inrange(len(nums)-3): for idx2 inrange(idx1+1,len(nums)-2): left = idx2 + 1 right = len(nums) - 1
while left < right: val = nums[idx1]+nums[idx2]+nums[left]+nums[right] if val < target: left += 1 elif val > target: right -= 1 else: if [nums[idx1],nums[idx2],nums[left],nums[right]] notin res: res.append([nums[idx1],nums[idx2],nums[left],nums[right]]) left += 1 right -= 1 return res
classSolution: deffourSum(self, nums, target): res = [] ifnot nums: return res
nums.sort()
for idx1 inrange(len(nums)-3): # 优化1 if idx1 != 0and nums[idx1] == nums[idx1-1]: continue for idx2 inrange(idx1+1,len(nums)-2): # 优化2 if idx2 != idx1 + 1and nums[idx2] == nums[idx2-1]: continue
left = idx2 + 1 right = len(nums) - 1
while left < right: val = nums[idx1] + nums[idx2] + nums[left] + nums[right] if val < target: left += 1 elif val > target: right -= 1 else: if [nums[idx1],nums[idx2],nums[left],nums[right]] notin res: res.append([nums[idx1],nums[idx2],nums[left],nums[right]]) left += 1 right -= 1 # 优化3 while left < right and nums[left] == nums[left-1]: left += 1 # 优化4 while left < right and nums[right] == nums[right+1]: right -= 1 return res
给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:
给定的 n 保证是有效的。
进阶:
你能尝试使用一趟扫描实现吗?
使用双指针法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
classSolution: defremoveNthFromEnd(self, head, n): slow = fast = head # 先让fast走n步 for i inrange(n): fast = fast.next # 若走了n步后为None,则表明删除的为head节点 if fast == None: return head.next
# slow和fast同时往前走 # 当fast走到头时,second即是要删除节点的前一个节点位置 while fast.next != None: slow = slow.next fast = fast.next # 删除该节点 slow.next = slow.next.next return head
deffun(strs): for i inrange(len(strs)): if strs[i].count('(') == n: strs[i]+=')' elif strs[i].count('(') > strs[i].count(')'): strs.append(strs[i]+'(') strs[i]+=')' else: strs[i]+='(' iflen(strs[0])==2*n: return fun(strs)
strs=['('] fun(strs) return strs
或者:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution: defgenerateParenthesis(self, n): res = ['()'] if n==0: return if n==1: return res for i inrange(n-1): tmp = [] for item in res: for j inrange(len(item)): # 每一个位置都加一个括号 tmp.append(item[:j+1]+'()'+item[j+1:]) res = list(set(tmp)) return res
classSolution: defuniquePathsWithObstacles(self, obstacleGrid: List[List[int]]): ifnot obstacleGrid: return0 m = len(obstacleGrid) n = len(obstacleGrid[0]) matrix = [[0]*n for i inrange(m)]
for i inrange(m): for j inrange(n): if obstacleGrid[i][j] == 1: matrix[i][j] = 0 else: if i==0and j==0: matrix[i][j] = 1 else: matrix[i][j]=matrix[i-1][j]+matrix[i][j-1] return matrix[m-1][n-1]