简单题型
1.两数之和
class Solution:
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
if nums == None or len(nums)<=0:
return None
for i in range(len(nums)):
for j in range(i+1,len(nums)):
if nums[i] + nums[j] == target:
return [i,j]
2.两数相加
链表逆序存储,相加输出一个新的逆序链表
class Solution:
def addTwoNumbers(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
if l1 == None:
return l2
if l2 == None:
return l1
tmp = ListNode(0) # 引用一个新的链表节点
res = tmp # res为输出的新链表
flag = 0 # 定义进位
while l1 or l2:
tmp_sum = 0 # 保存每一位节点的和
if l1:
tmp_sum += l1.val
l1 = l1.next
if l2:
tmp_sum += l2.val
l2 = l2.next
tmp_res = (tmp_sum + flag)%10
flag = (tmp_sum + flag)//10
res.next = ListNode(tmp_res)
res = res.next
if flag:
res.next = ListNode(1)
res = tmp.next # 赋值
del tmp # 删除tmp变量
return res
7.反转整数
class Solution:
def reverse(self, x):
"""
:type x: int
:rtype: int
"""
if -1010:
return x
s = str(x)
if s[0] != '-':
s = s[::-1]
x = int(s)
else:
s = s[1:][::-1]
x = int(s)
x = -x
return x if -2147483648 < x < 2147483647 else 0
9.回文数
class Solution:
def isPalindrome(self, x):
"""
:type x: int
:rtype: bool
"""
s = str(x)
if s[0] == '-':
return False
else:
s1 = s[::-1]
if s1 == s:
return True
else:
return False
13.罗马数字转整数
class Solution:
def romanToInt(self, s):
"""
:type s: str
:rtype: int
"""
map = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
sum = 0
for i in range(len(s)):
if i+1 == len(s) or map[s[i]]>=map[s[i+1]]:
sum += map[s[i]]
else:
sum -= map[s[i]]
return sum
14.最长公共前缀
class Solution:
def longestCommonPrefix(self, strs):
"""
:type strs: List[str]
:rtype: str
"""
if strs == None or len(strs)<=0:
return ''
s1 = min(strs)
s2 = max(strs)
for i, c in enumerate(s1):
# 比较是否相同的字符串,不相同则使用下标截取字符串
if c != s2[i]:
return s1[:i]
return s1
20.有效的括号
我的解法,利用stack判断左右括号一一对应
class Solution(object):
def isValid(self, s):
"""
:type s: str
:rtype: bool
"""
if len(s) % 2 == 1:
return False
d = {'{': '}', '[': ']', '(': ')'}
stack = []
for i in s:
# in stack
if i in d:
stack.append(i)
else:
if not stack or d[stack.pop()] != i:
return False
if stack:
return False
else:
return True
偶然间看到的大神的更简洁的解法
l = [None]是列表中含有None,列表长度依然为1。l = [],列表长度才为0。在定义列表l的时候就是l = [None],初始长度就为1,所以最后返回的判断用len(l) == 1来判断。
class Solution:
def isValid(self, s):
"""
:type s: str
:rtype: bool
"""
a = {')':'(', ']':'[', '}':'{'}
l = [None]
for i in s:
if i in a and a[i] == l[-1]:
l.pop()
else:
l.append(i)
return len(l)==1
21.合并有序链表
class Solution:
def mergeTwoLists(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
if l1 == None:
return l2
if l2 == None:
return l1
if l1.val <= l2.val:
l1.next = self.mergeTwoLists(l1.next,l2)
return l1
elif l2.val <= l1.val:
l2.next = self.mergeTwoLists(l1,l2.next)
return l2
26.删除排序数组中的重复项
两个快慢指针遍历一遍整个数组
class Solution:
def removeDuplicates(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
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]
else:
continue
return i+1
28.实现strStr()
class Solution:
def strStr(self, haystack, needle):
"""
:type haystack: str
:type needle: str
:rtype: int
"""
if needle == None:
return 0
length1 = len(haystack)
length2 = len(needle)
for i in range(length1-length2+1):
if haystack[i:i+length2] == needle:
return i
break
return -1
35.搜索插入位置
class Solution:
def searchInsert(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
if len(nums) == 0:
return 0
for i in range(len(nums)):
if nums[i] >= target:
return i
elif nums[i] < target and i+1continue
else:
return len(nums)
206.反转链表
class Solution:
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if head == None:
return None
Reversehead = None
cur = head
pre = None
while cur != None:
pnext = cur.next
if next == None:
Reversehead = cur
cur.next = pre
pre = cur
cur = pnext
return pre
203.删除链表中的节点
创建虚拟头节点
深刻理解链表的指针指向,要注意头节点的前一个节点的判断情况
class Solution:
def removeElements(self, head, val):
"""
:type head: ListNode
:type val: int
:rtype: ListNode
"""
dummyhead = ListNode(0)
dummyhead.next = head
cur = dummyhead
while(cur.next != None):
if cur.next.val == val:
delnode = cur.next
cur.next = delnode.next
delnode.next = None
else:
cur = cur.next
retnode = dummyhead.next
return retnode
24.两两交换链表中的节点
class Solution:
def swapPairs(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
dummyhead = ListNode(0)
dummyhead.next = head
p = dummyhead
while p.next and p.next.next:
node1 = p.next
node2 = node1.next
next = node2.next
node2.next = node1
node1.next = next
p.next = node2
p = node1
retnode = dummyhead.next #注意返回的是虚拟头节点的next
return retnode
147.对链表插入排序
class Solution:
def insertionSortList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
# 创建一个虚拟节点指向头节点
helper = ListNode(None)
helper.next = head
# 如果不用排序直接next
while head and head.next:
if head.next.val > head.val:
head = head.next
continue
# 需要插入排序的情况
cur = head.next # head.next与head交换
head.next = head.next.next
# 找到前面再次排序的插入点
pre = helper
while pre.next and pre.next.val# 插入交换
cur.next = pre.next
pre.next = cur
return helper.next
237.删除链表中的节点
考虑不必要穿针引线,本题利用改变节点的值来解决删除某一给定节点
class Solution:
def deleteNode(self, node):
"""
:type node: ListNode
:rtype: void Do not return anything, modify node in-place instead.
"""
if node == None:
return
if node.next == None:
node == None
return
node.val = node.next.val
node.next = node.next.next
return
19.删除链表中的倒数第N个节点
两个节点同时遍历链表,找到要删除节点的前一个节点即可
class Solution:
def removeNthFromEnd(self, head, n):
"""
:type head: ListNode
:type n: int
:rtype: ListNode
"""
while n>0:
dummyhead = ListNode(0)
dummyhead.next = head
p = dummyhead
q = dummyhead
for i in range(n+1):
q = q.next
while q!=None:
p = p.next
q = q.next
delnode = p.next
p.next = delnode.next
del delnode
resnode = dummyhead.next
del dummyhead
return resnode
8.字符串转整数
利用正则化解决字母索引问题,还可以用ASCll码解决字母,数字的索引问题
class Solution:
def myAtoi(self, str):
"""
:type str: str
:rtype: int
"""
import re #引入正则化模块
#正则化中^代表用^后面的开头,[-+]?表示[-+]可以出现,也可以不出现,\d匹配所有数字,\d+数字后面可以连接无数数字,但不能是其他东西,包括空格和字母
list_s = re.findall(r"^[-+]?\d+", str.strip()) #删除前,后空格。这样容易导致开始碰到字母就为空列表
#print(list_s)
if not list_s:
return 0 #字母开始列表是空的,直接返回0
else:
num =int(''.join(list_s)) #列表转化为字符串,然后转化为整数
if num >2**31 -1:
return 2**31 -1
elif num < -2**31:
return -2**31
else:
return num
283.将0放在列表的所有非0元素之后
思路一:利用O(n)的辅助空间完成0元素的后移
时间复杂度O(n)
空间复杂度O(n)
class Solution:
def moveZeroes(self, nums):
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
alist = []
for i in range(len(nums)):
if nums[i]:
alist.append(nums[i])
for i in range(len(alist)):
nums[i] = alist[i]
for i in range(len(alist),len(nums)):
nums[i] = 0
思路二:不使用辅助空间,原地完成0元素后移
时间复杂度O(n)
空间复杂度O(1)
class Solution:
def moveZeroes(self, nums):
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
k = 0
for i in range(len(nums)):
if nums[i]:
nums[k]=nums[i]
k+=1
for i in range(k,len(nums)):
nums[i] = 0
思路三:直接交换0和非0元素
class Solution:
def moveZeroes(self, nums):
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
k = 0
for i in range(len(nums)):
if nums[i]:
tmp = nums[k]
nums[k]=nums[i]
nums[i] = tmp
k+=1
27.移除元素
原地移除,O(1)的空间复杂度
思路一:
class Solution:
def removeElement(self, nums, val):
"""
:type nums: List[int]
:type val: int
:rtype: int
"""
k = 0
for i in range(len(nums)):
if nums[i] != val:
nums[k] = nums[i]
k+=1
return k
思路二:删除元素之后顺序可以改变,不断将最后一个元素替换val的元素即可
class Solution:
def removeElement(self, nums, val):
"""
:type nums: List[int]
:type val: int
:rtype: int
"""
i = 0
n = len(nums)
while iif nums[i] == val:
nums[i] = nums[n-1]
n -= 1
else:
i+=1
return n
75.颜色分类
思路一:计数排序,简单解法
时间复杂度O(n)
空间复杂度O(k)
class Solution:
def sortColors(self, nums):
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
count = [0]*3
for i in range(len(nums)):
if nums[i]==0:
count[0]+=1
if nums[i]==1:
count[1]+=1
if nums[i]==2:
count[2]+=1
index = 0
for i in range(count[0]):
nums[index]=0
index+=1
for i in range(count[1]):
nums[index]=1
index+=1
for i in range(count[2]):
nums[index]=2
index+=1
思路二:三路快排
时间复杂度O(n)
空间复杂度O(1)
只需遍历数组一次
class Solution:
def sortColors(self, nums):
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
zero = -1
two = len(nums)
i = 0
while iif nums[i]==1:
i+=1
elif nums[i]==2:
two -=1
nums[i],nums[two] = nums[two],nums[i]
elif nums[i]==0:
zero +=1
nums[i],nums[zero] = nums[zero],nums[i]
i+=1
88.合并两个有序数组
从后向前比较,将nums1和nums2中的最大值放在数组的最后的位置,不断向前遍历
class Solution:
def merge(self, nums1, m, nums2, n):
"""
:type nums1: List[int]
:type m: int
:type nums2: List[int]
:type n: int
:rtype: void Do not return anything, modify nums1 in-place instead.
"""
if n==0:
return
elif m==0 and n>=0:
for i in range(n):
nums1[i]=nums2[i]
else:
i = m-1
j = n-1
k = m+n-1
while i>=0 and j>=0:
if nums1[i]>nums2[j]:
nums1[k]=nums1[i]
i -=1
else:
nums1[k]=nums2[j]
j-=1
k-=1
while i>=0:
nums1[k]=nums1[i]
i-=1
k-=1
while j>=0:
nums1[k]=nums2[j]
j-=1
k-=1
53.最大子序和
很巧妙的动态规划解法,直接在数组中原地求和,如果前n项和比第n+1项的值还小,那直接从n+1从新往后加和
class Solution:
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
for i in range(1,len(nums)):
if nums[i-1] > 0:
nums[i] += nums[i-1]
return max(nums)
167.两数之和 II - 输入有序数组
思路一:暴力两层遍历,时间复杂度O(n^2),会超时
思路二:二分搜索,时间复杂度O(nlgn)
思路三:对撞指针,时间复杂度O(n)
class Solution:
def twoSum(self, numbers, target):
"""
:type numbers: List[int]
:type target: int
:rtype: List[int]
"""
if len(numbers)<2:
return
left = 0
right = len(numbers)-1
while leftif numbers[left]+numbers[right] == target:
return [left+1,right+1]
elif numbers[left]+numbers[right] < target:
left += 1
else:
right -= 1
209.长度最小的子数组
思路一:暴力遍历,不可取,有O(n^3)和O(n^2)的两种遍历,时间复杂度太大,不可取
思路二:滑动窗口,前后两个指针一起移动遍历数组
做数组类型的题目时要多考虑这种解法,不然python速度慢,暴力遍历情况大多会超时
class Solution:
def minSubArrayLen(self, s, nums):
"""
:type s: int
:type nums: List[int]
:rtype: int
"""
length = len(nums)
sum = 0
left = 0
right = -1 #初始化右边界,不包含任何元素
res = length+1 #初始化结果的最大边界,即不可能达到的边界
if nums == []:
return 0
while left < length:
if sumand right1:
right += 1
sum += nums[right]
else:
sum -= nums[left]
left += 1
if sum >= s:
res = min(res,right-left+1)
if res == length+1:
return 0
return res
3.误重复字符的最长子串
思路:滑动窗口,若右指针的右边的字符跟现在的子串不重复,右指针+1,若右指针右边的字符重复,则左指针向右移动,直到将最右的重复字符剔除为止。
class Solution:
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
length = len(s)
l = 0
r = -1
res = 0
freq = [0]*256
while lif r+1and freq[ord(s[r+1])]==0:
r += 1
freq[ord(s[r])]+=1
else:
freq[ord(s[l])]-=1
l += 1
res = max(res,r-l+1)
return res
144.二叉树的前序遍历
class Solution(object):
def preorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
if not root:
return []
elif not root.left and not root.right:
return [root.val]
l = self.preorderTraversal(root.left)
r = self.preorderTraversal(root.right)
return [root.val]+l+r
94.中序遍历
class Solution(object):
def inorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
if not root:
return []
if not root.left and not root.right:
return [root.val]
l = self.inorderTraversal(root.left)
r = self.inorderTraversal(root.right)
return l+[root.val]+r
145.后序遍历
class Solution(object):
def postorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
if not root:
return []
if not root.left and not root.right:
return [root.val]
l = self.postorderTraversal(root.left)
r = self.postorderTraversal(root.right)
return l+r+[root.val]