题目地址:https://leetcode.cn/problems/valid-palindrome/description/?envType=study-plan-v2&envId=top-interview-150
详见代码。
class Solution:
def isPalindrome(self, s: str) -> bool:
newStr = ""
s = s.lower()
for c in s:
if (c >= "a" and c <= "z") or (c >= "0" and c <= "9"):
newStr += c
left, right = 0, len(newStr)-1
while(left<=right):
if newStr[left] != newStr[right]:
return False
left += 1
right -= 1
return True
题目地址:https://leetcode.cn/problems/is-subsequence/description/?envType=study-plan-v2&envId=top-interview-150
双指针挨个遍历 s s s和 t t t中的字符,看能否找到相对位置一致的字串。
class Solution:
def isSubsequence(self, s: str, t: str) -> bool:
s_len = len(s)
t_len = len(t)
s_index = 0
if s_len == 0:
return True
if t_len == 0:
return False
for i in range(t_len):
if s_index == s_len:
break
if s[s_index] == t[i]:
s_index += 1
if s_index == s_len:
return True
else:
return False
题目地址:https://leetcode.cn/problems/two-sum-ii-input-array-is-sorted/description/?envType=study-plan-v2&envId=top-interview-150
双指针前后遍历元素,找到合适的值。
class Solution:
def twoSum(self, numbers: List[int], target: int) -> List[int]:
left, right = 0, len(numbers)-1
while(left < right):
if numbers[left] + numbers[right] > target:
right -= 1
elif numbers[left] + numbers[right] < target:
left += 1
else:
break
return [left+1,right+1]
题目地址:https://leetcode.cn/problems/container-with-most-water/description/?envType=study-plan-v2&envId=top-interview-150
木桶原理,水最多取决于左右边界更短的那个边界,所以希望最短边界尽可能长。
class Solution:
def maxArea(self, height: List[int]) -> int:
left, right = 0, len(height)-1
max_water = 0
while left < right:
tmp_water = min(height[left],height[right])*(right-left)
max_water = max(max_water,tmp_water)
if height[left] <= height[right]:
left += 1
else:
right -= 1
return max_water
题目地址:https://leetcode.cn/problems/3sum/description/?envType=study-plan-v2&envId=top-interview-150
先排序,然后去重,每次固定一个数,在剩下的范围中用双指针找合为0的三元组。
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
length = len(nums)
ans = []
if length < 3:
return ans
nums.sort()
for i in range(length):
if nums[i] > 0:
return ans
if i > 0 and nums[i] == nums[i-1]:
continue
left = i + 1
right = length - 1
while left < right:
if nums[i] + nums[left] + nums[right] == 0:
ans.append([nums[i],nums[left],nums[right]])
while left<right and nums[left] == nums[left+1]:
left += 1
while left<right and nums[right] == nums[right-1]:
right -= 1
left += 1
right -= 1
elif nums[i] + nums[left] + nums[right] < 0:
left += 1
else:
right -= 1
return ans
题目地址:https://leetcode.cn/problems/minimum-size-subarray-sum/description/?envType=study-plan-v2&envId=top-interview-150
设置滑动窗口比较窗口内的数字之和与 t a r g e t target target,当满足条件时去掉窗口内首元素,将窗口右移,再次比较。
class Solution:
def minSubArrayLen(self, target: int, nums: List[int]) -> int:
length = len(nums)
slow, fast = 0, 0
sum, ans = 0, length+1
while fast < length:
sum += nums[fast]
while sum >= target:
ans = min(ans,fast-slow+1)
sum -= nums[slow]
slow += 1
fast += 1
return 0 if ans==length+1 else ans
题目地址:https://leetcode.cn/problems/longest-substring-without-repeating-characters/description/?envType=study-plan-v2&envId=top-interview-150
详见代码。
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
max_len = 0
tmp_str = ""
length = len(s)
i = 0
while i < length:
if s[i] not in tmp_str:
tmp_str += s[i]
max_len = max(max_len,len(tmp_str))
i += 1
else:
while s[i] in tmp_str:
tmp_str = tmp_str[1:]
return max_len
题目地址:https://leetcode.cn/problems/substring-with-concatenation-of-all-words/description/?envType=study-plan-v2&envId=top-interview-150
依次比较每个滑动窗口中单词的出现次数与 w o r d s words words是否一致即可。
class Solution:
def findSubstring(self, s: str, words: List[str]) -> List[int]:
word_len = len(words[0])
word_num = len(words)
window = word_len * word_num
ans = []
cnt = {word:0 for word in words}
word_cnt = cnt.copy()
for word in words:
word_cnt[word] += 1
start = 0
while start < len(s) - window + 1:
tmp_cnt = cnt.copy()
for i in range(start, start+window, word_len):
tmp_word = s[i:i+word_len]
if tmp_word in tmp_cnt:
tmp_cnt[tmp_word] += 1
else:
break
if tmp_cnt == word_cnt:
ans.append(start)
start += 1
return ans
题目地址:https://leetcode.cn/problems/minimum-window-substring/description/?envType=study-plan-v2&envId=top-interview-150
class Solution:
def minWindow(self, s: str, t: str) -> str:
s_len, t_len, needCnt = len(s), len(t), len(t)
need = collections.defaultdict(int)
for c in t:
need[c] += 1
ans = (0,float('inf'))
# 增加右边界使滑窗包含t
i = 0
for j,c in enumerate(s):
if need[c] > 0:
needCnt -= 1
need[c] -= 1
# 收缩左边界直到无法再去掉元素
if needCnt == 0:
while True:
ch = s[i]
if need[ch] == 0:
break
else:
need[ch] += 1
i += 1
if j-i < ans[1]-ans[0]:
ans = (i,j+1)
# i多增加一个位置,准备开始下一次循环
need[s[i]] += 1
needCnt += 1
i += 1
return ""if ans[1]>s_len else s[ans[0]:ans[1]]
题目地址:https://leetcode.cn/problems/valid-sudoku/description/?envType=study-plan-v2&envId=top-interview-150
将数组分别按照行、列、块构造哈希表,判断是否有重复元素。
class Solution:
def isValidSudoku(self, board: List[List[str]]) -> bool:
row = [[0] * 9 for _ in range(9)]
col = [[0] * 9 for _ in range(9)]
block = [[0] * 9 for _ in range(9)]
for i in range(9):
for j in range(9):
if board[i][j] != '.':
num = int(board[i][j]) - 1
b = (i // 3) * 3 + j // 3
if row[i][num] or col[j][num] or block[b][num]:
return False
row[i][num] = col[j][num] = block[b][num] = 1
return True
题目地址:https://leetcode.cn/problems/spiral-matrix/description/?envType=study-plan-v2&envId=top-interview-150
设置上下左右边界,按照从左到右、从上到下、从右到左、从下到上的顺序挨个遍历即可。
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
l,r,t,b,res = 0,len(matrix[0])-1,0,len(matrix)-1,[]
while True:
# left to right
for i in range(l,r+1):
res.append(matrix[t][i])
t += 1
if t > b:
break
# top to bottom
for i in range(t,b+1):
res.append(matrix[i][r])
r -= 1
if r < l:
break
# right to left
for i in range(r,l-1,-1):
res.append(matrix[b][i])
b -= 1
if b < t:
break
# bottom to top
for i in range(b,t-1,-1):
res.append(matrix[i][l])
l += 1
if l > r:
break
return res
题目地址:https://leetcode.cn/problems/rotate-image/description/?envType=study-plan-v2&envId=top-interview-150
主对角线翻转+左右翻转。
class Solution:
def rotate(self, matrix: List[List[int]]) -> None:
length = len(matrix)
# 主对角线
for i in range(length):
for j in range(i+1,length):
matrix[i][j],matrix[j][i] = matrix[j][i],matrix[i][j]
# 左右
for i in range(length):
for j in range(length//2):
matrix[i][j],matrix[i][length-j-1] = matrix[i][length-j-1],matrix[i][j]
题目地址:https://leetcode.cn/problems/set-matrix-zeroes/description/?envType=study-plan-v2&envId=top-interview-150
首先判断第一行和第一列是否存在零,然后分别用第一行和第一列的空间表示该行或者该列是否存在零,最后统一置零即可。
class Solution:
def setZeroes(self, matrix: List[List[int]]) -> None:
row = len(matrix)
col = len(matrix[0])
zero_first = [False,False]
# 第一行是否有零
for i in range(col):
if matrix[0][i] == 0:
zero_first[0] = True
break
# 第一列是否有零
for i in range(row):
if matrix[i][0] == 0:
zero_first[1] = True
break
# 记录其他行和列的零
for i in range(1,row):
for j in range(1,col):
if matrix[i][j] == 0:
matrix[i][0] = matrix[0][j] = 0
# 矩阵置零
for i in range(1,row):
for j in range(1,col):
if matrix[i][0] == 0 or matrix[0][j] == 0:
matrix[i][j] = 0
if zero_first[0] == True:
for i in range(col):
matrix[0][i] = 0
if zero_first[1] == True:
for i in range(row):
matrix[i][0] = 0
题目地址:https://leetcode.cn/problems/game-of-life/description/?envType=study-plan-v2&envId=top-interview-150
卷积运算,计算每个细胞的得分。
import numpy as np
class Solution:
def gameOfLife(self, board: List[List[int]]) -> None:
row,col = len(board),len(board[0])
# zero padding
board_tmp = np.array([[0 for _ in range(col+2)] for _ in range(row+2)])
board_tmp[1:row+1,1:col+1] = np.array(board)
# kernel
kernel = np.array([[1,1,1],[1,0,1],[1,1,1]])
# conv
for i in range(1,row+1):
for j in range(1,col+1):
tmp = np.sum(kernel * board_tmp[i-1:i+2,j-1:j+2])
if board_tmp[i][j] == 1:
if tmp < 2 or tmp > 3:
board[i-1][j-1] = 0
else:
if tmp == 3:
board[i-1][j-1] = 1