1295. 统计位数为偶数的数字
题意:
求一个数组里位数为偶数个数。
python 使用list序列表达式 简洁(优美)写法:
class Solution:
def findNumbers(self, nums) -> int:
return [1 if len(str(num))%2 ==0 else 0 for num in nums].count(1)
c++ 啰嗦写法
class Solution {
public:
int findNumbers(vector<int>& nums) {
int ans = 0;
for(int num : nums){
int tmp = 0;
while(num){
num/=10;
tmp+=1;
}
if(tmp%2==0) ans+=1;
}
return ans;
}
};
1296. 划分数组为连续数字的集合
题意:
把n个数的数组划分成K个连续的集合。
实际上这题需要把这些数预处理出一个有序的key-value集合。
这种数据结构叫做TreeMap
, 在C++里STL封装好的的Map
就是符合这个性质,按照key值有序的排列。
在python里虽然没有直接有序的字典,但我们可以先用collection.count
统计频数,然后排序。
class Solution:
def isPossibleDivide(self, nums, k ):
import collections
s = collections.Counter(nums)
ordered_nums = sorted(s)
for num in ordered_nums:
cnt = s[num]
if cnt >0:
for i in range(num+1, num +k):
if s[i] >= cnt: s[i] -= cnt
else : return False
return True
class Solution {
public:
bool isPossibleDivide(vector<int>& nums, int k) {
map<int,int> ordered_nums;
for(auto &num:nums){
ordered_nums[num]+=1;
}
for(auto iter = ordered_nums.begin(); iter!=ordered_nums.end();iter++){
int num = iter->first;
int cnt = iter->second;
if(cnt>0){
auto it = next(iter);
for(int i=num+1;i<num+k;i++,it++){
if(it!=ordered_nums.end()&&i==it->first&&it->second>=cnt){
it->second -=cnt;
}
else{
return false;
}
}
}
}
return true;
}
};
补这题的时候,顺带补充了c++遍历vector,auto的相关语法。
1297. 子串的最大出现次数
题意:
给你一个字符串 s ,请你返回满足以下条件且出现次数最大的任意子串的出现次数:
- 子串中不同字母的数目必须小于等于 maxLetters 。
- 子串的长度必须大于等于 minSize 且小于等于 maxSize 。
思路:
非常直接暴力的思路,枚举统计所有满足条件的同时长度满足minSize<=len(s)<=maxSize
的字符串的出现次数,时间复杂度O(n*len(S)^2)。
分析可以知道maxSize是多余的条件,因为minSize子串满足条件一定是更长的真子集,所以只需要枚举长度为minSize并满足条件的子串个数,时间复杂度变成O(n*len(S))。
代码:
class Solution:
def maxFreq(self, s: str, maxLetters: int, minSize: int, maxSize: int) -> int:
n = len(s)
d = collections.defaultdict(int)
for i in range(n - minSize+1):
tmp = s[i:i+minSize]
c = collections.Counter(tmp)
if len(c) <= maxLetters:
d[tmp] +=1
return max(d.values()) if d else 0
另外python还有另一种思路一样的但耗时更少和更简洁的写法:
class Solution:
def maxFreq(self, s: str, maxLetters: int, minSize: int, maxSize: int) -> int:
return max(collections.Counter(s[i:i+minSize] for i in range(0,len(s)-minSize +1)
if len({*s[i:i+minSize]})<=maxLetters).values(),default=0)
这里面*string
作用是把字符串每个元素都split。
c++里的 unordered_set 可以用来统计容器里不同元素的操作第一次见!
class Solution {
public:
int maxFreq(string s, int maxLetters, int minSize, int maxSize) {
int n = s.length();
int ans = 0;
unordered_map<string,int> cot;
for(int i=0 ; i< n- minSize +1; i++){
string tmp = s.substr(i,minSize);
unordered_set<char> exist(tmp.begin(), tmp.end());
if(exist.size() <= maxLetters){
cot[tmp] +=1;
ans = max(ans, cot[tmp]);
}
}
return ans;
}
};
1298. 你能从盒子里获得的最大糖果数
思路:
很清楚就是一个bfs(广度优先搜索),首先用队列维护一个搜素顺序,然后用几个变量用来记录哪些搜索状态的变化。
注意:python写法里,我是用list的pop(0)模拟先进先出
的队列。
代码 :
class Solution:
def maxCandies(self, status ,candies, keys, containedBoxes, initialBoxes):
ans = 0
queue = []
boxs = [0] * len(status)
vis = [0] * len(status)
for box in initialBoxes:
boxs[box] = 1
if status[box]== 1:
ans += candies[box]
queue.append(box)
vis[box] = 1
while True:
if len(queue) == 0 : break
id = queue[0]
queue.pop(0)
for key in keys[id]:
if boxs[key] == 1 and vis[key]==0 :
queue.append(key)
ans += candies[key]
vis[key] =1
status[key] = 1
for box in containedBoxes[id]:
if status[box] == 1 and vis[box] ==0 :
queue.append(box)
ans += candies[box]
vis[box] = 1
boxs[box] = 1
return ans
这题c++写法没有什么特殊,就懒得补了。