LeetCode 第 19 场双周赛(231 / 1120,前20.6%)

文章目录

    • 1. 比赛结果
    • 2. 题目
      • LeetCode 5311. 将数字变成 0 的操作次数 easy
      • LeetCode 5312. 大小为 K 且平均值大于等于阈值的子数组数目 medium
      • LeetCode 5313. 时钟指针的夹角 medium
      • LeetCode 5314. 跳跃游戏 IV hard

1. 比赛结果

做出来了1, 3, 4题,第2题结束后12分钟做出来了。
全国排名:231/1120,20.6%;全球排名:772/3745,20.6%
LeetCode 第 19 场双周赛(231 / 1120,前20.6%)_第1张图片
LeetCode 第 19 场双周赛(231 / 1120,前20.6%)_第2张图片

2. 题目

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

题目链接
给你一个非负整数 num ,请你返回将它变成 0 所需要的步数。 如果当前数字是偶数,你需要把它除以 2 ;否则,减去 1 。

示例 1:
输入:num = 14
输出:6
解释:
步骤 1) 14 是偶数,除以 2 得到 7 。
步骤 27 是奇数,减 1 得到 6 。
步骤 36 是偶数,除以 2 得到 3 。
步骤 43 是奇数,减 1 得到 2 。
步骤 52 是偶数,除以 2 得到 1 。
步骤 61 是奇数,减 1 得到 0 。

示例 2:
输入:num = 8
输出:4
解释:
步骤 18 是偶数,除以 2 得到 4 。
步骤 24 是偶数,除以 2 得到 2 。
步骤 32 是偶数,除以 2 得到 1 。
步骤 41 是奇数,减 1 得到 0 。

示例 3:
输入:num = 123
输出:12
 
提示:
0 <= num <= 10^6

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-steps-to-reduce-a-number-to-zero
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


解答:

class Solution {
public:
    int numberOfSteps (int num) {
        int count = 0;
        while(num)
        {	
        	if(num%2 == 0)
        		num /= 2;
        	else
        		num -= 1;
        	count++;
        }
        return count;
    }
};

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

题目链接
给你一个整数数组 arr 和两个整数 k 和 threshold 。

请你返回长度为 k 且平均值大于等于 threshold 的子数组数目。

示例 1:
输入:arr = [2,2,2,2,5,5,5,8], k = 3, threshold = 4
输出:3
解释:子数组 [2,5,5],[5,5,5][5,5,8] 的平均值分别为 456 。其他长度为 3 的子数组的平均值都小于 4 (threshold 的值)。

示例 2:
输入:arr = [1,1,1,1,1], k = 1, threshold = 0
输出:5

示例 3:
输入:arr = [11,13,17,23,29,31,7,5,2,3], k = 3, threshold = 5
输出:6
解释:前 6 个长度为 3 的子数组平均值都大于 5 。注意平均值不是整数。

示例 4:
输入:arr = [7,7,7,7,7,7,7], k = 7, threshold = 7
输出:1

示例 5:
输入:arr = [4,4,4,4], k = 4, threshold = 1
输出:1

提示:
1 <= arr.length <= 10^5
1 <= arr[i] <= 10^4
1 <= k <= arr.length
0 <= threshold <= 10^4

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-sub-arrays-of-size-k-and-average-greater-than-or-equal-to-threshold
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


解题:

一开始看错题,子数组,我看成,可以随意组合。。。
双指针解题即可。

class Solution {
public:
    int numOfSubarrays(vector<int>& arr, int k, int threshold) {
        int i = 0, j = k-1, n = arr.size(), sum=0, target = k*threshold;
        int count = 0;
        for(i = 0; i < k; i++) 
        	sum += arr[i];
        if(sum >= target)
        	count++;
        i=1,j++;
        while(j < n)
        {
        	sum += arr[j]-arr[i-1];
        	if(sum >= target)
        		count++;
            i++,j++;
        }
        return count;
    }
};

LeetCode 5313. 时钟指针的夹角 medium

题目链接

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

提示:
1 <= hour <= 12
0 <= minutes <= 59
与标准答案误差在 10^-5 以内的结果都被视为正确结果。

解题:

class Solution {
public:
    double angleClock(int hour, int minutes) {
        double d1 = 0, d2 = 0;
        d2 = minutes*6;
        d1 = (hour%12)*30 + double(d2)/360*30;
        return min(abs(d1-d2),360-abs(d1-d2));
    }
};

LeetCode 5314. 跳跃游戏 IV hard

题目链接

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

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

  • i + 1 满足:i + 1 < arr.length
  • i - 1 满足:i - 1 >= 0
  • j 满足:arr[i] == arr[j] 且 i != j

请你返回到达数组最后一个元素的下标处所需的 最少操作次数

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

示例 1:
输入:arr = [100,-23,-23,404,100,23,23,23,3,404]
输出:3
解释:那你需要跳跃 3 次,下标依次为 0 --> 4 --> 3 --> 9 。
下标 9 为数组的最后一个元素的下标。

示例 2:
输入:arr = [7]
输出:0
解释:一开始就在最后一个元素处,所以你不需要跳跃。

示例 3:
输入:arr = [7,6,9,6,9,6,9,7]
输出:1
解释:你可以直接从下标 0 处跳到下标 7 处,也就是数组的最后一个元素处。

示例 4:
输入:arr = [6,1,9]
输出:2

示例 5:
输入:arr = [11,22,7,7,7,7,7,7,7,22,13]
输出:3
 
提示:
1 <= arr.length <= 5 * 10^4
-10^8 <= arr[i] <= 10^8

解题:

  • BFS, 广度优先搜索

开始想着用动态规划,后来知道不是,是最短路径问题。
先超时一次(连续一样的数,可以只插入最后一个即可,)
LeetCode 第 19 场双周赛(231 / 1120,前20.6%)_第3张图片
超时代码:

class Solution {
public:
    int minJumps(vector<int>& arr) {
        if(arr.size() == 1)
            return 0;
        int i, tp;
        const int n = arr.size();
        vector<int> dp(n, INT_MAX);
        queue<int> q;
        vector<bool> visited(n,false);
        q.push(0);
        visited[0] = true;
        dp[0] = 0;
        multimap<int, int> m;
        for(i = 1; i < n; i++)
            m.insert(make_pair(arr[i], i));
        while(!q.empty() && (dp[n-1] == INT_MAX))
        {
            tp = q.front();
            q.pop();
            if(tp+1 < n && !visited[tp+1])
            {
                dp[tp+1] = min(dp[tp+1], 1+dp[tp]);
                q.push(tp+1);
                visited[tp+1] = true;
            }
            if(tp-1>0 && !visited[tp-1])
            {
                dp[tp-1] = min(dp[tp-1], 1+dp[tp]);
                q.push(tp-1);
                visited[tp-1] = true;
            }
            if(dp[n-1] != INT_MAX)
                return dp[n-1];
            auto start = m.equal_range(arr[tp]).first, end = m.equal_range(arr[tp]).second;
            for(auto it = start; it != end; ++it)
            {
                if(!visited[it->second])
                {
                    visited[it->second] = true;
                    dp[it->second] = min(dp[it->second], 1+dp[tp]);
                    q.push(it->second);
                }
                if(dp[n-1] != INT_MAX)
                    return dp[n-1];
            }
        }
        return dp[n-1];
    }
};

通过代码:172ms

class Solution {
public:
    int minJumps(vector<int>& arr) {
        if(arr.size() == 1)
            return 0;
        int i, tp, prev = arr[0];
        const int n = arr.size();
        vector<int> dp(n, INT_MAX);
        queue<int> q;
        vector<bool> visited(n,false);
        q.push(0);
        visited[0] = true;
        dp[0] = 0;
        multimap<int, int> m;
        for(i = 0; i < n; i++)
        {
            if(arr[i] == prev)
                continue;
            else
            {
                m.insert(make_pair(prev, i-1));
                prev = arr[i];
            }
        }
        m.insert(make_pair(arr[n-1],n-1));
        while(!q.empty() && (dp[n-1] == INT_MAX))
        {
            tp = q.front();
            q.pop();
            if(tp+1 < n && !visited[tp+1])
            {
                dp[tp+1] = min(dp[tp+1], 1+dp[tp]);
                q.push(tp+1);
                visited[tp+1] = true;
            }
            if(tp-1>0 && !visited[tp-1])
            {
                dp[tp-1] = min(dp[tp-1], 1+dp[tp]);
                q.push(tp-1);
                visited[tp-1] = true;
            }
            if(dp[n-1] != INT_MAX)
                return dp[n-1];
            auto start = m.equal_range(arr[tp]).first, end = m.equal_range(arr[tp]).second;
            for(auto it = start; it != end; ++it)
            {
                if(!visited[it->second])
                {
                    visited[it->second] = true;
                    dp[it->second] = min(dp[it->second], 1+dp[tp]);
                    q.push(it->second);
                }
                if(dp[n-1] != INT_MAX)
                    return dp[n-1];
            }
        }
        return dp[n-1];
    }
};

赛后优化代码如下:

class Solution {
public:
    int minJumps(vector<int>& arr) {
        if(arr.size() == 1)
            return 0;
        int i, tp, prev = INT_MIN, step = 0, size;
        const int n = arr.size();
        queue<int> q;
        vector<bool> visited(n,false);
        q.push(0);
        visited[0] = true;
        multimap<int, int> m;
        for(i = 0; i < n; i++)
        {
            if(arr[i] == prev)
                continue;//跳过一样的
            else//只插入连续相同的一段的首尾,中间跳肯定不是最短距离
            {  
                if(i-1>=0)
                    m.insert(make_pair(arr[i-1],i-1));
                m.insert(make_pair(arr[i], i));
                prev = arr[i];
            }
            if(i == n-1)//插入最后一个位置,可能重复插入了,但是不影响
                m.insert(make_pair(arr[i],i));
        }

        while(!q.empty())
        {
            size = q.size();
            while(size--)
            {
                tp = q.front();
                q.pop();
                if(tp == n-1)
                    return step;

                // 跳往i+1位置
                if(tp+1 < n && !visited[tp+1])
                {
                    q.push(tp+1);
                    visited[tp+1] = true;
                }
                // 跳往i-1位置
                if(tp-1>0 && !visited[tp-1])
                {
                    q.push(tp-1);
                    visited[tp-1] = true;
                }
                
                // 跳往值相同的位置
                auto start = m.equal_range(arr[tp]).first, end = m.equal_range(arr[tp]).second;
                for(auto it = start; it != end; ++it)
                {
                    if(!visited[it->second])
                    {
                        visited[it->second] = true;
                        q.push(it->second);
                    }
                }
            }
            step++;
        }
        return step;
    }
};

LeetCode 第 19 场双周赛(231 / 1120,前20.6%)_第4张图片

你可能感兴趣的:(LeetCode)