题31(中等):
分析:
其实这题题目比较难懂,题目还是挺简单的
我们可以从后面末尾开始,如果前一个大于后面的,说明后面不用动,如果小于,那就找仅仅大于它的数字放前面,其他数字重新排序放后面,前面不用动
python代码:
class Solution:
def nextPermutation(self, nums: List[int]) -> None:
res_list = []
# 获取长度
nums_len = len(nums)
if nums_len==0 or nums_len==1:
return
# 从后面算要不要换
for i in range(nums_len - 1):
a = nums[nums_len - i - 1] # 去已经确定的头
b = nums[nums_len - i - 2] # 取新加的
if a > b:
res_list = nums[nums_len - i - 2:]
res_list = sorted(res_list)
index = res_list.index(b)
while 1:
index += 1
if res_list[index] != b:
break
res_list = nums[:nums_len - i - 2] + res_list[index:index + 1] + res_list[0:index] + res_list[index + 1:]
break
else:
if i==nums_len-2:
res_list = sorted(nums)
continue
nums.clear()
nums.extend(res_list)
题32(困难):
分析:
其实就是遍历一遍,我的思路就是每一项为前两项的和+2,且将前两项去了
python代码:
class Solution:
def longestValidParentheses(self, s: str) -> int:
tmp_list=[]
s_stack=[]
for i in s:
if i=="(":
s_stack.append(i)
tmp_list.append(0)
else:
if len(s_stack)!=0 and s_stack[-1]=='(':
s_stack.pop()
if tmp_list!=[]:
a1=tmp_list.pop()
else:
a1=0
if tmp_list!=[]:
a2=tmp_list.pop()
else:
a2=0
next=a1+a2+2
tmp_list.append(next)
else:
tmp_list.append(0)
return max(tmp_list) if tmp_list!= [] else 0
题33(中等):
分析:
这个和折半查找应该差不多吧
python代码:
class Solution:
def search(self, nums: List[int], target: int) -> int:
if nums[0]<nums[-1]:
nums=nums[:]+[nums[0]-abs(target)]
num_len=len(nums)
left = 0
right = num_len - 1
notice1=target>=nums[0]
notice2=target<=nums[-1]
if notice1==0 and notice2==0:
return -1
while left<=right:
mid=(left+right)//2
if notice1:
if nums[mid]==target:
return mid
elif nums[mid]<=nums[-1] or nums[mid]>target:
right=mid-1
else:
left=mid+1
continue
if notice2:
if nums[mid]==target:
return mid
elif nums[mid]>=nums[0] or nums[mid]<target:
left=mid+1
else:
right=mid-1
continue
return -1
题34(中等):
分析:
没什么好分析的,这波也是折半查找
python代码:
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
left=0
right=len(nums)-1
min_target=-1
while left<=right:
mid=(left+right)//2
if nums[mid]==target:
if mid-1>=0 and nums[mid-1]==target:
right=mid-1
else:
min_target=mid
break
elif nums[mid]<target:
left=mid+1
elif nums[mid]>target:
right=mid-1
max_target = -1
left = 0
right = len(nums) - 1
while left<=right:
mid=(left+right)//2
if nums[mid]==target:
if mid + 1 <= len(nums)-1 and nums[mid + 1] == target:
left = mid+1
else:
max_target = mid
break
elif nums[mid]<target:
left=mid+1
elif nums[mid]>target:
right=mid-1
return [min_target,max_target]
题35(简单):
python代码:
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
left=0
right=len(nums)-1
min_target=-1
while left<=right:
mid=(left+right)//2
if nums[mid]==target:
min_target=mid
break
elif nums[mid]<target:
left=mid+1
elif nums[mid]>target:
right=mid-1
return min_target if min_target!=-1 else right+1
题36(中等):
分析:
自己定义一个检查列表的函数,每次将一堆传过去检测
python代码:
class Solution:
def isValidSudoku(self, board: List[List[str]]) -> bool:
def isValidUnit(unit):
# 检查一个行、列或宫格是否有效
seen = set()
for num in unit:
if num != '.':
if num in seen:
return False
seen.add(num)
return True
for i in range(9):
if not isValidUnit(board[i]):
return False
for j in range(9):
column = [board[i][j] for i in range(9)]
if not isValidUnit(column):
return False
for i in range(0, 9, 3):
for j in range(0, 9, 3):
square = [board[x][y] for x in range(i, i+3) for y in range(j, j+3)]
if not isValidUnit(square):
return False
return True
题37(困难):
python代码:
class Solution:
def solveSudoku(self, board: List[List[str]]) -> None:
def Conflict(board):
def isValidUnit(unit):
# 检查一个行、列或宫格是否有效
seen = set()
for num in unit:
if num != '.':
if num in seen:
return False
seen.add(num)
return True
for i in range(9):
if not isValidUnit(board[i]):
return False
for j in range(9):
column = [board[i][j] for i in range(9)]
if not isValidUnit(column):
return False
for i in range(0, 9, 3):
for j in range(0, 9, 3):
square = [board[x][y] for x in range(i, i + 3) for y in range(j, j + 3)]
if not isValidUnit(square):
return False
return True
def run(n):
for i in range(n,81):
x = i // 9
y = i % 9
if board[x][y]!='.':
continue
for j in range(1,10):
board[x][y]=str(j)
if Conflict(board) and run(i+1):
return True
board[x][y]='.'
return False
return True
run(0)
题38(中等):
分析:
用上一个的值生成下一个,用递归最好,其实迭代也挺简单,用数组来接受每一次生成的数据即可
python代码:
class Solution:
@staticmethod
def toString(str1):
t_list = []
res = ''
for i in range(len(str1)):
if t_list!=[] and t_list[0]!=str1[i]:
res=res+str(len(t_list))+t_list[0]
t_list=[]
t_list.append(str1[i])
res=res+str(len(t_list))+t_list[0]
return res
def countAndSay(self, n: int) -> str:
if n==1:
return '1'
else:
newstr=self.countAndSay(n-1)
print(newstr)
return Solution.toString(newstr)
题39(中等):
分析:
以后写代码先写注释再写代码,思路更清晰,分析再代码中
python代码:
class Solution:def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:#这个组合题思路肯定是递归,非线性的嘛#先排好序s_can=sorted(candidates)self.res=[]self.call_back(candidates,target,[],0)return self.respassdef call_back(self,candidates,target,n_list,k):#对m操作,这样回溯更稳, 注意深拷贝和浅拷贝m=n_list.copy()#如果target==0,说明已经找到了一组解,将m加入resif target==0:self.res.append(m)return#如果target<0,说明已经超了,直接返回if target<0:return#如果target>0,说明还有剩余,继续递归,借助k来看现在当前最小的是哪个数字,n_list是已经找到的数字if target>0:for i in range(k,len(candidates)):self.call_back(candidates,target-candidates[len(candidates)-i-1],n_list+[candidates[len(candidates)-i-1]],i)
看起来好像代码背景比块背景好看唉
题40(中等):
分析:
见代码注释区域
python代码:
class Solution:def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:#不重复思路肯定也是递归s_can=sorted(candidates)self.res=[]self.call_back(s_can,target,[])return self.resdef call_back(self,s_can,target,res_list):#如果值等于0,则加入resif target==0:self.res.append(res_list)return#如果值小于0或者数组为空,则退出if target<0 or len(s_can)==0:return#如果值大于0,则递归,注意,我们是从高位开始,所以我们是要找小的,不能找大的for i in range(len(s_can)):#如果该项和上一项相同,则跳过if i>0 and s_can[len(s_can)-i-1]==s_can[len(s_can)-i]:continuek=s_can[len(s_can)-1-i]new_target=target-knew_list=res_list.copy()new_list.append(k)new_scan=s_can[0:len(s_can)-1-i]self.call_back(new_scan,new_target,new_list)