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++寫法沒有什麼特殊,就懶得補了。