1.独一无二的出现次数
题目描述:给定一个整数数组arr
,如果数组中数字出现的次数各不相同则返回True
,否则返回False
。
思路:统计就可以了,利用set
不包含重复元素的特性,查看长度是否相等即可。
代码:
from collections import defaultdict
class Solution:
def uniqueOccurrences(self, arr: List[int]) -> bool:
d = defaultdict(int)
for num in arr:
d[num] += 1
if len(d.values()) == len(set(d.values())):
return True
else:
return False
2.尽可能使字符串相等
题目描述:给定长度相等的字符串s
,t
,使s
与t
的第i
个字符相等的开销为两个字符ASCII
码差值的绝对值。在最大开销预算maxCost
的限定下,返回相等的子字符串的最大长度。
思路:给定字符串后,很容易得到每个字符转化的开销数组,记为record
。那么该问题就转化为,整数数组中和小于设定值的最小子数组长度。
代码:
class Solution:
def equalSubstring(self, s: str, t: str, maxCost: int) -> int:
record = [abs(ord(s[i]) - ord(t[i])) for i in range(len(s))]
start, end, cost = 0, 0, 0
l, res = 0, 0
print(record)
while end < len(t):
if cost + record[end] <= maxCost:
l += 1
cost += record[end]
end += 1
res = max(res, l)
else:
l -= 1
cost -= record[start]
start += 1
return res
3.删除字符串中所有的相邻重复项II
题目描述:给定字符串s
和整数k
,删除s
中k
个相邻且相等的字母,直到无法删除位置。需要注意的是,在一次删除之后,被删字符左右两侧可能又组成了需要被删的长度为k的相等字符,需要继续删除。
思路:利用栈来做:遍历字符串,如果栈空或者栈顶字符与当前字符不等,则添加到栈中;若相等,则将当前元素加到栈顶字符串中,若长度为k
,则将栈顶元素弹出。
代码:
class Solution:
def removeDuplicates(self, s: str, k: int) -> str:
stack = []
for c in s:
if not stack or stack[-1][-1] != c:
stack.append(c)
else:
stack[-1] += c
if len(stack[-1]) == k:
stack.pop()
return ''.join(stack)
4.穿越迷宫的最少移动次数
题目描述:蛇的长度为2
,迷宫大小为n*n
,迷宫中0
代表空单元格,1
代表障碍物。求蛇从左上角(0,0)和(0,1)
移动到右下角(n-1, n-2)和(n-1,n-1)
的最小移动次数。
蛇的移动方式:1、整体横向、纵向移动;2、如果蛇所在的四方格内均为障碍物,则蛇可以调整水平、竖直状态。
思路:此类问题容易想到用动态规划来做。这道题的难点在于,蛇占了两个单元格,且有水平、竖直两种状态。蛇的移动可以根据蛇所在四方格内有无障碍物来划分:如果有障碍物,那么蛇只能沿着原方向前进;如果没有,那么蛇可以整体平移、调整方向。
代码:
class Solution:
def minimumMoves(self, grid: List[List[int]]) -> int:
n = len(grid)
dp = [[[float('inf') for _ in range(2)] for _ in range(n)] for _ in range(n)]
dp[0][0][0] = 0
for i in range(n):
for j in range(n):
if not grid[i][j]:
# 有四方格,可以调整方向,或者做平移
if i + 1 < n and j + 1 < n and not grid[i+1][j] and not grid[i][j+1] and not grid[i+1][j+1]:
# 水平方向可以由竖直方向逆时针旋转过来
dp[i][j][0] = min(dp[i][j][0], dp[i][j][1]+1)
# 竖直方向可以由水平方向逆时针旋转过来
dp[i][j][1] = min(dp[i][j][0] + 1, dp[i][j][1])
# 水平下移
dp[i+1][j][0] = min(dp[i+1][j][0], dp[i][j][0] + 1)
# 竖直右移
dp[i][j+1][1] = min(dp[i][j+1][1], dp[i][j][1] + 1)
# 没有四方格,只能往前移动
if j + 2 < n and not grid[i][j+1] and not grid[i][j+2]:
dp[i][j+1][0] = min(dp[i][j+1][0], dp[i][j][0] + 1)
if i + 2 < n and not grid[i+1][j] and not grid[i+2][j]:
dp[i+1][j][1] = min(dp[i+1][j][1], dp[i][j][1] + 1)
return dp[n-1][n-2][0] if dp[n-1][n-2][0] != float('inf') else -1