leetcode 168 周賽題解

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章