目录
1309. Decrypt String from Alphabet to Integer Mapping-easy。string
1310. XOR Queries of a Subarray-medium。prefix sum
1311. Get Watched Videos by Your Friends-medium。BFS/sort
1312. Minimum Insertion Steps to Make a String Palindrome-hard。DP
Given a string s
formed by digits ('0'
- '9'
) and '#'
. We want to map s
to English lowercase characters as follows:
'a'
to 'i')
are represented by ('1'
to '9'
) respectively.'j'
to 'z')
are represented by ('10#'
to '26#'
) respectively. Return the string formed after mapping.
It's guaranteed that a unique mapping will always exist.
Example 1:
Input: s = "10#11#12"
Output: "jkab"
Explanation: "j" -> "10#" , "k" -> "11#" , "a" -> "1" , "b" -> "2".
Example 2:
Input: s = "1326#"
Output: "acz"
Example 3:
Input: s = "25#"
Output: "y"
Example 4:
Input: s = "12345678910#11#12#13#14#15#16#17#18#19#20#21#22#23#24#25#26#"
Output: "abcdefghijklmnopqrstuvwxyz"
Constraints:
1 <= s.length <= 1000
s[i]
only contains digits letters ('0'
-'9'
) and '#'
letter.s
will be valid string such that mapping is always possible.题意比较直接,可以确定一个固定的pattern就是两位数字后是否为'#'
class Solution:
def freqAlphabets(self, s: str) -> str:
if not s:
return s
n = len(s)
i = 0
res = []
while i < n:
if (i+2 < n and s[i+2] == '#') or (i+1 < n and s[i+1] == '0'): # or后面的条件可以不写
cur = int(s[i:i+2])
# res.append(chr(cur-1 + ord('a')))
i += 2
else:
cur = int(s[i])
res.append(chr(cur-1 + ord('a')))
i += 1
return ''.join(res)
Given the array arr
of positive integers and the array queries
where queries[i] = [Li, Ri]
, for each query i
compute the XOR of elements from Li
to Ri
(that is, arr[Li] xor arr[Li+1] xor ... xor arr[Ri]
). Return an array containing the result for the given queries
.
Example 1:
Input: arr = [1,3,4,8], queries = [[0,1],[1,2],[0,3],[3,3]]
Output: [2,7,14,8]
Explanation:
The binary representation of the elements in the array are:
1 = 0001
3 = 0011
4 = 0100
8 = 1000
The XOR values for queries are:
[0,1] = 1 xor 3 = 2
[1,2] = 3 xor 4 = 7
[0,3] = 1 xor 3 xor 4 xor 8 = 14
[3,3] = 8
Example 2:
Input: arr = [4,8,2,10], queries = [[2,3],[1,3],[0,0],[0,3]]
Output: [8,0,4,4]
Constraints:
1 <= arr.length <= 3 * 10^4
1 <= arr[i] <= 10^9
1 <= queries.length <= 3 * 10^4
queries[i].length == 2
0 <= queries[i][0] <= queries[i][1] < arr.length
根据输入的constraint暴力不可行。 利用前缀和的思想,que[l, r]的结果直接由que[0, l-1] ^ que[0, r]决定,所以先建立好一个计算截止nums[i]的连续异或的结果的数组。
也有极简做法,写一个solve函数,输入参数等于queries每一个子query的元素个数,再用map函数
class Solution:
def xorQueries(self, arr: List[int], queries: List[List[int]]) -> List[int]:
if not queries or not arr:
return []
res = []
n = len(arr)
prefix = [0]*(n+1)
for i in range(n):
prefix[i+1] = arr[i] ^ prefix[i]
for que in queries:
l = que[0]
r = que[1]
cur = prefix[r+1] ^ prefix[l]
res.append(cur)
return res
# 最简做法
class Solution(object):
def xorQueries(self, A, queries):
P = [0]
for x in A:
P.append(P[-1] ^ x)
def solve((left, right)):
return P[right + 1] ^ P[left]
return map(solve, queries)
There are n
people, each person has a unique id between 0
and n-1
. Given the arrays watchedVideos
and friends
, where watchedVideos[i]
and friends[i]
contain the list of watched videos and the list of friends respectively for the person with id = i
.
Level 1 of videos are all watched videos by your friends, level 2 of videos are all watched videos by the friends of your friends and so on. In general, the level k of videos are all watched videos by people with the shortest path equal to k with you. Given your id
and the level
of videos, return the list of videos ordered by their frequencies (increasing). For videos with the same frequency order them alphabetically from least to greatest.
Example 1:
Input: watchedVideos = [["A","B"],["C"],["B","C"],["D"]], friends = [[1,2],[0,3],[0,3],[1,2]], id = 0, level = 1
Output: ["B","C"]
Explanation:
You have id = 0 (green color in the figure) and your friends are (yellow color in the figure):
Person with id = 1 -> watchedVideos = ["C"]
Person with id = 2 -> watchedVideos = ["B","C"]
The frequencies of watchedVideos by your friends are:
B -> 1
C -> 2
Example 2:
Input: watchedVideos = [["A","B"],["C"],["B","C"],["D"]], friends = [[1,2],[0,3],[0,3],[1,2]], id = 0, level = 2
Output: ["D"]
Explanation:
You have id = 0 (green color in the figure) and the only friend of your friends is the person with id = 3 (yellow color in the figure).
Constraints:
n == watchedVideos.length == friends.length
2 <= n <= 100
1 <= watchedVideos[i].length <= 100
1 <= watchedVideos[i][j].length <= 8
0 <= friends[i].length < n
0 <= friends[i][j] < n
0 <= id < n
1 <= level < n
friends[i]
contains j
, then friends[j]
contains i
主流做法是先用BFS找到距离id长度为level的所有节点,然后把这些节点看过的剧用字典汇总,再排序输出
写的过程中出现的问题是没有用visited来保证之前访问过的节点不再重复访问,如果不用会把距离id距离<=level的所有节点都记录下来。
from collections import deque
class Solution:
def watchedVideosByFriends(self, watchedVideos: List[List[str]], friends: List[List[int]], id: int, level: int) -> List[str]:
if not watchedVideos or not friends:
return []
res = {}
k = level
q = deque((id,))
visited = set()
visited.add(id)
while k > 0:
k -= 1
for _ in range(len(q)):
cur = q.popleft()
for friend in friends[cur]:
if friend not in visited:
q.append(friend)
visited.add(friend)
for f in q:
for v in watchedVideos[f]:
res[v] = res.get(v, 0) + 1
ans = []
for k, v in sorted(res.items(), key = lambda kv: (kv[1], kv[0])):
ans.append(k)
return ans
Given a string s
. In one step you can insert any character at any index of the string.
Return the minimum number of steps to make s
palindrome.
A Palindrome String is one that reads the same backward as well as forward.
Example 1:
Input: s = "zzazz"
Output: 0
Explanation: The string "zzazz" is already palindrome we don't need any insertions.
Example 2:
Input: s = "mbadm"
Output: 2
Explanation: String can be "mbdadbm" or "mdbabdm".
Example 3:
Input: s = "leetcode"
Output: 5
Explanation: Inserting 5 characters the string becomes "leetcodocteel".
Example 4:
Input: s = "g"
Output: 0
Example 5:
Input: s = "no"
Output: 1
Constraints:
1 <= s.length <= 500
s
are lower case English letters.DP的思想,和palindrome系列一样。只是在首尾不相等时是在在右添加一个首字母还是在左边添加一个尾字母间选一个代价更小的方案
class Solution:
def minInsertions(self, s: str) -> int:
if not s:
return 0
n = len(s)
dp = [[500 for _ in range(n)] for _ in range(n)]
for i in range(n):
dp[i][i] = 0
for j in range(i-1, -1, -1):
if s[i] == s[j]:
dp[j][i] = dp[j+1][i-1] if i-j > 2 else 0 # 因为dp[j][i]依赖的是dp[j+1][i-1],所以j要从大到小变化
else:
dp[j][i] = min(dp[j+1][i], dp[j][i-1]) + 1
return dp[0][n-1]
# 只消耗系统栈和cache的方法
from functools import lru_cache
class Solution:
def minInsertions(self, s: str) -> int:
INF = float('inf')
@lru_cache(None)
def dp(i, j):
if i > j:
return INF
elif i == j:
return 0
elif i == j-1:
return +(s[i] != s[j])
elif s[i] == s[j]:
return dp(i+1, j-1)
else:
return min(dp(i, j-1), dp(i+1, j)) + 1
return dp(0, len(s) - 1)