No.1: Two Sum
思路:一个下标循环记录,先定当前记录的数据,然后寻找下一个与之匹配的数据。
查找时可用hashmap查找,python3中的index(value)方法就是查找在一个数组范围内的value所对应的下标,如nums[i+1:].index(second)
class Solution:
def twoSum(self, nums, target):
for i in range(len(nums)):
second = target - nums[i]
if second in nums[i+1:]:
j = nums[i+1:].index(second) + i + 1
return i,j
No.2:Add Two Numbers
思路:先把两个链表元素reverse转为整数,然后整数相加再变成链表。注意无论是链转int还是int转链都要reverse。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def addTwoNumbers(self, l1, l2):
res1 = 0;res2 = 0;
i1 = i2 = 0
while l1 or l2:
if l1:
res1 = res1 + l1.val * (10 ** i1)
i1 += 1
l1 = l1.next
if l2:
res2 = res2 + l2.val * (10 ** i2)
i2 += 1
l2 = l2.next
res = res1 + res2;out = []
if res == 0:
out = [0]
while res:
out.append(res % 10)
res //= 10
return out
No.3:Longest Substring Without Repeating Characters
思路:Sliding Windows(移窗法),声明一个buf数组记录已经记录的字符串,用ij控制开始和结束的下标。当一个字母在buf中没出现过,则记录并更新ans=max(ans,j-i+1),然后j++;如果出现,则删除s[i]这个数值然后i++。最后return ans的值。
class Solution:
def lengthOfLongestSubstring(self, s):
ans = i = j = 0
buf = []
while i<len(s) and j<len(s):
if s[j] not in buf:
buf.append(s[j])
ans = max(ans,j-i+1)
j += 1
else:
buf.remove(s[i])
i += 1
return ans
No.7:Reverse Integer
思路:首先分情况,小于0的数标记后去绝对值,然后每次提取各位再加到结果的最前面,最后再对小于0的数添负号
class Solution:
def reverse(self, x):
res = 0
flag = False
if x < 0:
flag = True
x = abs(x)
while x != 0:
res = res * 10 + x % 10
x = math.floor(x/10)
if res>=math.pow(2,31):
return 0
else:
if flag == True:
res = -res
return res
No.9:Palindrome Number
思路:判断一个数是否是回文数。
- 首先,负数一定不是回文数,单独拉出来判断
- 然后,对于非负数,先加个tmp用来保存x的初值,然后依据规则,根据x生成回文数,比较生成的回文数与原来的x是否相同,相同则返回true,否则返回false。
注意,每次往前推tmp的时候要向下取整
class Solution: def isPalindrome(self, x): if x < 0: return False tmp = x y = 0 while tmp: y = y * 10 + tmp % 10 tmp = math.floor(tmp/10) if x == y: return True else: return False
No.13:Roman to Integer
思路:题意为判断罗马数字的数值,规则为根据字母对应数值,而且小接大为减法,大接小为加法。所以先把字母转成数字,然后根据规则进行加减法运算即可class Solution: def romanToInt(self, s): sum = 0 t = {"I":1,"V":5,"X":10,"L":50,"C":100,"D":500,"M":1000} ans = [] for i in str(s): ans.append(t[i]) print(ans) for i in range(len(s)-1): if ans[i] < ans[i+1]: sum = sum - ans[i] else: sum = sum + ans[i] sum = sum + ans[-1] return sum
No.14:Longest Common Prefix
思路:先假设第一个字符串最大,然后与后面的字符串比较取相同的最长前缀字符串,然后往后不断比较直至到最后找出最长的公共前缀字符串
class Solution: def longestCommonPrefix(self, strs): if len(strs) == 0: return "" prefix = strs[0] for i in range(1,len(strs)): if not prefix: #prefix为空 return "" else: while prefix not in strs[i][:len(prefix)] and len(prefix) > 0: prefix = prefix[:len(prefix)-1] return prefix
No.20:Valid Parentheses
思路:括号匹配,将括号后与括号前分别做成key-value的map对应,遇到前部分符号,进栈。当找到后部分时,符号出栈,与对应的value比较,如果不符,则返回false,否则返回trueclass Solution: def isValid(self, s): pars = [None] parmap = {'}':'{',']':'[',')':'('} for c in s: if c in parmap: if parmap[c] != pars.pop(): return False else: pars.append(c) return len(pars) == 1
No.21:Merge Two Sorted Lists
思路:将两个排好序的链表重新按顺序Merge。
首先,比较l1和l2在表头的值,将较小的那个链表next链接指向较大的链表头结点,这样就保证了总是较小数值的排在前面。最后观察哪个链表为空,就输出另外一个链表。
#Definition for singly-linked list. #class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: def mergeTwoLists(self, l1, l2): if l1 is None: return l2 if l2 is None: return l1 if l1.val < l2.val: l1.next = self.mergeTwoLists(l1.next,l2) return l1 else: l2.next = self.mergeTwoLists(l1,l2.next) return l2
No.26:Remove Duplicates from Sorted Array
思路1:[99ms],用两个指针进行循环比较,i为外循环、j为内循环,然后当nums[i]==nums[j]时,j++;不相等时,i向前推进,然后令nums[i]=nums[j]。最后返回i+1class Solution: def removeDuplicates(self, nums): if len(nums) == 0: return 0 i = 0 for j in range(1,len(nums)): if nums[j] != nums[i]: i += 1 nums[i] = nums[j] return i + 1
思路2:从后往前遍历数组,如发现相同的元素,就删除,最后返回数组的长度
class Solution: def removeDuplicates(self, nums): if nums == []: return 0 for i in range(len(nums)-1,0,-1): if nums[i] == nums[i-1]: del nums[i] return len(nums)
No.27:Remove Element
思路:在不开辟新数组的情况下,移除值为val的元素并返回新数组长度。
利用双指针来做,i和j一快一慢,当nums[i]==val时,i++;不等于时,将后面非val的值赋值到前面,并更新j++。结束时,只需返回j即可。新数组就位于nums[:j],后面可以不访问而得到class Solution: def removeElement(self, nums, val): j = 0 for i in range(len(nums)): if nums[i] != val: nums[j] = nums[i] j += 1 return j
No.28:Implement strStr()
思路1:直接利用python的index(str)函数,如果substring存在在string中,则返回substring的index值,否则返回-1class Solution: def strStr(self, haystack, needle): if needle in haystack: return haystack[:].index(needle) else: return -1
思路2:循环遍历一次,每次查找string[i:i+len(substring)]是否等于substring,找到则返回i,否则返回-1
class Solution: def strStr(self, haystack, needle): f = False for i in range(len(haystack) - len(needle) + 1): if haystack[i:i+len(needle)] == needle: return i f = True if f == False: return -1
No.35:Search Insert Position
思路1:循环遍历一遍数组,如果找到target,直接返回下标;如果最左边大于target,返回0;如果最右边小于target,返回len(nums)+1;如果在中间出现一个小于target一个大于target的数,返回中间的下标值class Solution: def searchInsert(self, nums, target): for i in range(len(nums)): if nums[i] == target: return i if i == len(nums) - 1 and nums[i] < target: return i + 1 if i == 0 and nums[i] >target: return i if nums[i] < target and nums[i+1] > target: return i + 1
思路2:由于是排序好的数组,故可用二分搜索,如果nums[i]>target,则往左边找,更新r的值;如果nums[i]<target,则往右边找,更新l的值。如果r - l <= 1,代表已锁定数组下标的位置,返回r。如果nums[i] == target,直接返回下标值
class Solution: def searchInsert(self, nums, target): if nums[0] >= target: return 0 if nums[-1] < target: return len(nums) elif nums[-1] == target: return len(nums) - 1 l = 0;r = len(nums) - 1 while r - l > 1: mid = (l + r) // 2 if nums[mid] > target: r = mid elif nums[mid] == target: return mid else: l = mid return r
No.743:(Contest)Network Delay Time
思路:题意为给定一个有向有权重图,问从顶点K开始,经过多少时间能遍历全图。这题思路可以先将所有顶点置为INF,然后将K点置为0,接着从顶点出发查找邻点,如果找到且a[fr]+wei<a[to]时,代表是最短路径,更新a[to]的值,最后取a数组的最大值即可。如果发现有顶点值仍然为INF,代表没有被访问,输出-1。class Solution: def networkDelayTime(self, times, N, K): a = [] for i in range(N+1): a.append(1e6)#代表没有被访问的顶点 a[K] = 0 for i in range(N): for j in range(len(times)): fr = times[j][0] to = times[j][1] wei = times[j][2] if a[fr] + wei < a[to]: a[to] = a[fr] + wei ans = 0 for i in range(1,N+1): if ans < a[i]: ans = a[i] if a[i] == 1e6: return -1 return ans
No.38:Count and Say
思路:给定第一个字符串,构造后面的字符串,构造规则为
全加(重复的次数+重复的数字)关于python的正则表达式: 模块:import re re.findall(规则,目标字符串) r'(A)':忽略转义字符,以A规则查找 \number:第number个重复的数字, (.):匹配任意字符串 *:匹配任意个字符,紧跟在要匹配字符串后
python实现代码:
def countAndSay(self, n): s = '1' for _ in range(n - 1): s = ''.join(str(len(group)) + digit for group, digit in re.findall(r'((.)\2*)', s)) return s