classSolution: deftwoSum(self, nums: List[int], target: int) -> List[int]: hashmap={} ## 使用哈希表,以空间换时间,只用遍历一遍数组 for i,num in enumerate(nums): if hashmap.get(target - num) isnotNone: ## 字典遍历只需O(1) return [hashmap.get(target - num),i] hashmap[num] = i
三数之和
classSolution: defthreeSum(self, nums: List[int]) -> List[List[int]]: n = len(nums) if n < 3: return [] res = [] nums.sort() ## 需要先排序 ## 枚举a for first in range(n): ## 需要枚举的值和上次不一样 if first > 0and nums[first] == nums[first-1]: continue third = n-1## 先让c指向数组的最右端 target = -nums[first] ## 枚举b for second in range(first+1,n): ## 需要枚举的值和上次不一样 if second > first+1and nums[second] == nums[second-1]: continue ## b指针一直在c指针的左边,并且当两者的和一直大于target,那c指针一直后退 while second < third and nums[second] + nums[third] > target: third -= 1 ## 当遍历结束没有找到,则就结束这次循环 if second == third: break ## 当找到之后,保存到结果的数组中 if nums[second] + nums[third] == target: res.append([nums[first],nums[second],nums[third]]) return res
# class ListNode: # def __init__(self, x): # self.val = x # self.next = None
classSolution: defaddTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode: head = curr = ListNode() carry = val = 0 while carry or l1 or l2: ## 判断是否还有进位或者链表还未遍历结束 val = carry
if l1: l1,val = l1.next, l1.val + val ## l1存在,则值相加,指针后移 if l2: l2,val = l2.next, l2.val + val
classSolution: defconvert(self, s: str, numRows: int) -> str: if numRows == 1: return s ## 当只有一行的时候只用输出就好了
res = [""for _ in range(numRows)] ## numRow行的数组 curRow = 0## 初始指针为0 flag = -1## 作为开始和边界的标志,来判断是否开始转
for c in s: res[curRow] += c if curRow == 0or curRow == numRows - 1: ## 当刚开始或者已经完要转弯 flag = -flag curRow += flag ## 更改数组内小数组的坐标
return"".join(res)
7. 整数反转
classSolution: defreverse(self, x: int) -> int: rev = 0 y = abs(x) ## 先取正 while y != 0: pop = y % 10## 获取最后一个数字 y = int(y/10) ## 获取剩下的数字 ## 判断溢出,当rev>max/10,一定会溢出;或者rev=max/10,那么pop>7就会溢出 ## 7 = max%10 -8= min%10 if rev > (pow(2,31)-1)/10or (rev > (pow(2,31)-1)/10and pop > 7): return0 ## 判断溢出,当rev<min/10,一定会溢出;或者rev=min/10,那么pop<-8就会溢出 if rev < -pow(2,31)/10or (rev < -pow(2,31)/10and pop < -8): return0 ## rev = rev * 10 + pop ## 反转逐个求和 return rev if x>0else -rev ## 加符号
12. 整数转罗马数字
classSolution: defintToRoman(self, num: int) -> str: list1 = [1000,900,500,400,100,90,50,40,10,9,5,4,1] list2 = ['M','CM','D','CD','C','XC','L','XL','X','IX','V','IV','I'] result = "" length = len(list1) for i in range(length): while num >= list1[i]: ## 贪心算法 result += list2[i] num -= list1[i] return result
13. 罗马数字转整数:把一个小值放在大值的左边,就是做减法,否则为加法。
classSolution: defromanToInt(self, s: str) -> int: luoma = { 'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000 } i = 0 value = 0 length = len(s) while(i < length-1): if luoma[s[i]] >= luoma[s[i+1]]: ## 正常顺序做加法 value += luoma[s[i]] i += 1 else: ## 否则把一个小值放在大值的左边,就是做减法 value -= luoma[s[i]] i += 1 if i == length-1: ## 最后一个数的时候,需要加上 value += luoma[s[i]] return value
14. 最长公共前缀
classSolution: deflongestCommonPrefix(self, strs: List[str]) -> str: ifnot strs: return"" length,count = len(strs[0]),len(strs) for i in range(length): c = strs[0][i] ## 第一个字符的第i位,纵向扫描 ## any()函数用于判断给定的可迭代参数 iterable 是否全部为 False,则返回 False,如果有一个为 True,则返回 True。 if any(i==len(strs[j]) or strs[j][i] != c for j in range(1,count)): return strs[0][:i] return strs[0]
26. 删除有序数组中的重复项 双指针法
classSolution: defremoveDuplicates(self, nums: List[int]) -> int: lens = len(nums) if lens == 0: return0 i = 0## 慢指针 for j in range(0,lens): ## 快指针,当相等,则j不断增加 if nums[i] != nums[j]: ## 遇到不重复项 i += 1 nums[i] = nums[j] ## ,将其赋值到i+1这个位置上 return i+1
27. 移除元素 双指针法
classSolution: defremoveElement(self, nums: List[int], val: int) -> int: i= 0## 慢指针 n = len(nums) for j in range(n): ## 快指针 if nums[j] != val: ## 当不是删除的元素,就转移到慢指针所在的位置 nums[i] = nums[j] i += 1
dp = [[0]*n for _ in range(m)] ## 里面乘的是列,外面的是行 dp[0][0] = grid[0][0] ## 初始化开始
for j in range(1,n): ## 填充第1列,每次前面和当前的和 dp[0][j] = dp[0][j-1] + grid[0][j]
for i in range(1,m): ## 填充第1行,每次前面和当前的和 dp[i][0] = dp[i-1][0] + grid[i][0] for i in range(1,m): for j in range(1,n): ## 最小的和当前的和 dp[i][j] = min(dp[i-1][j],dp[i][j-1]) + grid[i][j] return dp[m-1][n-1] ## 返回最后一个值