第19场双周赛总结

2020-02-10

5311. 将数字变成 0 的操作次数

给你一个非负整数 num ,请你返回将它变成 0 所需要的步数。 如果当前数字是偶数,你需要把它除以 2 ;否则,减去 1 。
class Solution {
public:
    int numberOfSteps (int num) {
        int count = 0;
        while(num){
            if(num &1) num--;
            else num /= 2;
            count++;
        }
        return count;
    }
};

1343. 大小为 K 且平均值大于等于阈值的子数组数目

滑动串口,每次加上最后一个减去最前面一个;
class Solution {
public:
    int numOfSubarrays(vector<int>& arr, int k, int threshold) {
         int sum = k*threshold;
        int i, j;
        int count = 0;
        int temp = 0;//这里的初始化,永远的痛
        int n = arr.size();
        for(i = 0; i < k; i++)
            temp += arr[i];
        i = 0;
        j = k;
        while( j < n){
            if(temp >= sum) count++;
            temp += arr[j] - arr[i];
            j++;
            i++;
            //cout << temp << endl;
        }
        if(temp >= sum) count++;
        return count;
    }
};

5313. 时钟指针的夹角

给你两个数 hour 和 minutes 。请你返回在时钟上,由给定时间的时针和分针组成的较小角的角度(60 单位制)。

数学题:不过写得不够简洁:
class Solution {
public:
    double angleClock(int hour, int minutes) {
        double res;
        double h,m;
        m = minutes*6;
        h = hour*30 + minutes*0.5;
        if(h > m){
            res = h - m;
            if(res >= 180) return 360-res;
            else return res;
        }
        else{
            res = m - h;
            if(res >= 180) return 360-res;
            else return res;
        }
        return res;
    }
};

比较简洁:abs是求整数绝对值,fabs是求double和float的绝对值;

class Solution {
public:
    double angleClock(int hour, int minutes) {
        double k1 = 6 * minutes;
        double k2 = 30 * hour + 0.5 * minutes;
        return min(fabs(k1 - k2), 360 - fabs(k1 - k2));
    }
};

1345. 跳跃游戏 IV

给你一个整数数组 arr ,你一开始在数组的第一个元素处(下标为 0)。

每一步,你可以从下标 i 跳到下标:

i + 1 满足:i + 1 < arr.length
i - 1 满足:i - 1 >= 0
j 满足:arr[i] == arr[j] 且 i != j
请你返回到达数组最后一个元素的下标处所需的 最少操作次数 。

注意:任何时候你都不能跳到数组外面。

数据量不能使用O(N^2)的算法:

T了:每次都找前一个或者后一个,然后遍历一遍整个数组查找相同的;

class Solution {
public:
    int minJumps(vector<int>& arr) {
        int n = arr.size();
        vector<int> vis(n,0);
        vis[0] = 1;
        queue<int> q;
        q.push(0);
        int res = 0;
        while(!q.empty()){
            int l = q.size();
            for(int i = 0; i <l; i++){
                int t = q.front();
                q.pop();
                //cout << arr[t] << ' ';
                if(t == n-1) return res;
                if(t-1>=0 && vis[t-1] == 0){
                     q.push(t-1);vis[t-1] =1;
                }
                if(t+1 < n && vis[t+1]== 0){
                       q.push(t+1); vis[t+1] =1;}
                for(int i = 0; i <n;i++){
                    if(vis[i] == 0 && arr[i] == arr[t] && i!= t){
                       q.push(i),vis[i] = 1;}
                }
            }
           //cout << endl;
            res++;
        }
        return res;
    }
};        

对map的运用还是不熟悉,虽然想到map了,但是还是想坐标与值的map,没有想到值与多个坐标的对应关系,之前没有遇到过:

class Solution {
public:
    map<int,vector<int>> mp;//这个没想到,整数对应数组
    int minJumps(vector<int>& arr) {
        int n = arr.size();
        for(int i = 0; i < n;i++) mp[arr[i]].push_back(i);
        vector<int> vis(n,0);
        vis[0] = 1;
        queue<int> q;
        q.push(0);
        int res = 0;
        while(!q.empty()){
            int len = q.size();
            while(len--){
                 int t = q.front();q.pop();
            if(t == n-1) return res;
            if(t-1>= 0 && !vis[t-1]++) q.push(t-1);
            if(t+1 < n && !vis[t+1]++) q.push(t+1);
            auto it = mp.find(arr[t]);
            if (it != mp.end()){
                for(auto x: mp[arr[t]]){
                    if(!vis[x]++) q.push(x);
                }
                mp.erase(it);// 如果没有,当数据有很多重复元素时,会退化成n的平方
            }
            }
            res++;
        }
        return res;
    }
};

猜你喜欢

转载自www.cnblogs.com/Aliencxl/p/12291375.html