记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
10/25 240. 搜索二维矩阵 II
首先判断目标值是否比最小的小 比最大的大 如果满足直接返回不存在
因为从左往右 从上到下是升序的
可以从左下角开始考虑 (x,y)
将当前x,y与右上角组成的矩阵看做当前考虑矩阵
如果matrix[x,y]<target 此时对于当前列 i<x 都小于matrix[x,y]不满足 所以将点往右移动 y+=1
如果matrix[x,y]==target 返回true
如果matrix[x,y]>target 此时对于当前行 i>y 都大于matrix[x,y]不满足 所以将点往上移动 x-=1
如果超出矩阵范围 返回false
def searchMatrix(matrix, target):
"""
:type matrix: List[List[int]]
:type target: int
:rtype: bool
"""
m = len(matrix)
n = len(matrix[0])
if target<matrix[0][0] or target>matrix[m-1][n-1]:
return False
x,y=m-1,0
while x>=0 and y<n:
value = matrix[x][y]
if value==target:
return True
if value<target:
y+=1
else:
x-=1
return False
10/26 496. 下一个更大元素 I
vmap用来记录每个值右边大于他的第一个值
l单调栈用来保存当前状态
将当前值v与栈顶元素比较
如果v大于栈顶元素 说明v是栈顶元素最近的一个大值
取出栈顶元素 继续比较
完成比较后 将v压入栈中
def nextGreaterElement(nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: List[int]
"""
vmap = {}
l = []
for v in nums2:
vmap[v]=-1
while l:
prev = l[-1]
if prev<v:
vmap[prev] = v
l = l[:-1]
else:
break
l.append(v)
ans = []
for num in nums1:
ans.append(vmap[num])
return ans
10/27 301. 删除无效的括号
(和)分开来考虑
处理(时 从头开始计数(+1 )-1 如果小于0了 就说明)多余了 此时可以从当前位置往前的所有)中去除一个来保证序列的正确性
继续递归从下一个位置开始检查 这里lastj是记录上一次去除的位置 之后去除要在这个位置之后防止重复
当(处理完成后 将其倒序 同样检查)
def removeInvalidParentheses(s):
"""
:type s: str
:rtype: List[str]
"""
global ret
ret = []
def remove(s,lasti,lastj,ch):
global ret
count =0
for i in range(lasti,len(s)):
if(s[i] == "(" or s[i]==")"):
if s[i]==ch:
count-=1
else:
count+=1
if count>=0:
continue
for j in range(lastj,i+1):
if(s[j] == ch and (j == lastj or s[j - 1] != ch) ):
news = s[:j]+s[j+1:]
remove(news,i,j,ch)
return
ress = s[::-1]
if ch==")":
return remove(ress,0,0,"(")
else:
ret.append(ress)
remove(s,0,0,")")
return ret
10/28 869. 重新排序得到 2 的幂
n<109 所以2的幂最多229
找到所有2的幂的数字组合
匹配
def reorderedPowerOf2(n):
"""
:type n: int
:rtype: bool
"""
base = 1
s = set()
l = list(str(base))
l.sort()
s.add("".join(l))
for i in range(29):
base *=2
l = list(str(base))
l.sort()
s.add("".join(l))
check = list(str(n))
check.sort()
return "".join(check) in s
10/29 335. 路径交叉
归纳成三种情况
1.走了四步
第四步与第一步相交
条件:第3步小于等于第1步;第4步大于等于第2步
2.走了五步
第五步与第一步重合相交
条件:第4步等于第2步;第5步大于等于第3步-第1步,第3步>第1步
3.走了六步
第六步与第一步相交
第5步>=第3步-第1步 and <=第3步
第4步>第2步 and 第6步>=第4步-第2步
def isSelfCrossing(distance):
"""
:type distance: List[int]
:rtype: bool
"""
n = len(distance)
for i in range(3,n):
if distance[i]>=distance[i-2] and distance[i-1]<=distance[i-3]:
return True
if i>=4 and distance[i-3]==distance[i-1] and distance[i]>=distance[i-2]-distance[i-4]:
return True
if i>=5 and distance[i-3]-distance[i-1]<=distance[i-1]<=distance[i-3] and distance[i]>=distance[i-2]-distance[i-4] and distance[i-2]>distance[i-4]:
return True
return False
10/30 260. 只出现一次的数字 III
有两个数不同 那么求取所有数的异或xor 等于不同的两个数a,b的异或
因为a!=b那么xor至少有一位等于1 而在这一位上a,b中一个等于0,一个等于1
所以可以将所有数根据这一位是否等于1 分为两组 一组包含了a,另一组包含了b
那么对这两组的数取分别都异或 一组为a 一组为b
def singleNumber(nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
xor,a,b,mask=0,0,0,1
for num in nums:
xor ^=num
while xor&mask==0:
mask<<=1
for num in nums:
if num&mask:
a ^=num
else:
b ^=num
return [a,b]
10/31 500. 键盘行
rowIdx 记录从a-z每个单词的行数
如果在同一行则添加入答案中
def findWords(words):
"""
:type words: List[str]
:rtype: List[str]
"""
ans = []
rowIdx = "12210111011122000010020202"
for word in words:
idx = rowIdx[ord(word[0].lower()) - ord('a')]
if all(rowIdx[ord(ch.lower()) - ord('a')] == idx for ch in word):
ans.append(word)
return ans