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++写法没有什么特殊,就懒得补了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值