Featured image of post LeetCode第315场周赛总结

LeetCode第315场周赛总结

---/6490

没打

【模拟】与对应负数同时存在的最大正整数

题目

给你一个 不包含 任何零的整数数组 nums ,找出自身与对应的负数都在数组中存在的最大正整数 k

返回正整数 k ,如果不存在这样的整数,返回 -1

示例 1:

1
2
3
输入:nums = [-1,2,-3,3]
输出:3
解释:3 是数组中唯一一个满足题目要求的 k 。

示例 2:

1
2
3
输入:nums = [-1,10,6,7,-7,1]
输出:7
解释:数组中存在 1 和 7 对应的负数,7 的值更大。

示例 3:

1
2
3
输入:nums = [-10,8,6,7,-2,-3]
输出:-1
解释:不存在满足题目要求的 k ,返回 -1 。

提示:

  • 1 <= nums.length <= 1000
  • -1000 <= nums[i] <= 1000
  • nums[i] != 0

解题思路

按题意模拟即可

代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Solution {
public:
    int findMaxK(vector<int>& nums) {
        int res = -1;
        unordered_set<int> tab;
        for(auto &x:nums) tab.insert(x);
        for(auto &x: nums){
            if(x>0 && tab.count(-x)) res = max(res, x);
        }
        return res;
    }
};

【模拟】反转之后不同整数的数目

题目

给你一个由 整数组成的数组 nums

你必须取出数组中的每个整数,反转其中每个数位,并将反转后得到的数字添加到数组的末尾。这一操作只针对 nums 中原有的整数执行。

返回结果数组中 不同 整数的数目。

示例 1:

1
2
3
4
5
输入:nums = [1,13,10,12,31]
输出:6
解释:反转每个数字后,结果数组是 [1,13,10,12,31,1,31,1,21,13] 。
反转后得到的数字添加到数组的末尾并按斜体加粗表示。注意对于整数 10 ,反转之后会变成 01 ,即 1 。
数组中不同整数的数目为 6(数字 1、10、12、13、21 和 31)。

示例 2:

1
2
3
4
输入:nums = [2,2,2]
输出:1
解释:反转每个数字后,结果数组是 [2,2,2,2,2,2] 。
数组中不同整数的数目为 1(数字 2)。

提示:

  • 1 <= nums.length <= 10^5
  • 1 <= nums[i] <= 10^6

解题思路

按题意模拟即可

代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
class Solution {
public:
    int countDistinctIntegers(vector<int>& nums) {
        set<int> tab;
        for(auto x: nums){
            tab.insert(x);
            int u = 0;
            while(x){
                int tail = x%10;
                x = x/10;
                u = 10*u + tail;
            }
            tab.insert(u);
        }
        return tab.size();
    }
};

【枚举】反转之后的数字和

题目

给你一个 非负 整数 num 。如果存在某个 非负 整数 k 满足 k + reverse(k) = num ,则返回 true ;否则,返回 false

reverse(k) 表示 k 反转每个数位后得到的数字。

示例 1:

1
2
3
输入:num = 443
输出:true
解释:172 + 271 = 443 ,所以返回 true 。

示例 2:

1
2
3
输入:num = 63
输出:false
解释:63 不能表示为非负整数及其反转后数字之和,返回 false 。

示例 3:

1
2
3
输入:num = 181
输出:true
解释:140 + 041 = 181 ,所以返回 true 。注意,反转后的数字可能包含前导零。

提示:

  • 0 <= num <= 10^5

解题思路

枚举即可

代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
class Solution {
public:
    int rev(int num){
        int res = 0;
        while(num){
            res = 10*res+num%10;
            num/=10;
        }
        return res;
    }
    bool sumOfNumberAndReverse(int num) {
        for(int i=0;i<=num;i++){
            if(i+rev(i) == num) return true;
        }
        return false;
    }
};

【枚举+统计子数组】统计定界子数组的数目

题目

给你一个整数数组 nums 和两个整数 minK 以及 maxK

nums 的定界子数组是满足下述条件的一个子数组:

  • 子数组中的 最小值 等于 minK
  • 子数组中的 最大值 等于 maxK

返回定界子数组的数目。

子数组是数组中的一个连续部分。

示例 1:

1
2
3
输入:nums = [1,3,5,2,7,5], minK = 1, maxK = 5
输出:2
解释:定界子数组是 [1,3,5] 和 [1,3,5,2] 。

示例 2:

1
2
3
输入:nums = [1,1,1,1], minK = 1, maxK = 1
输出:10
解释:nums 的每个子数组都是一个定界子数组。共有 10 个子数组。

提示:

  • 2 <= nums.length <= 10^5
  • 1 <= nums[i], minK, maxK <= 10^6

解题思路

考虑以nums[i]结尾的合法数组,是否合法取决于:[0..i]范围内的minK、maxK出现情况,以及[minK, maxK]范围之外的数的出现情况

那么,维护三个东西:存储minK出现位置的数组,存储maxK出现位置的数组,存储范围之外的数出现位置的数组

(实际上,只需要维护出现的最后一个位置即可)

代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Solution {
public:
    long long countSubarrays(vector<int>& nums, int minK, int maxK) {
        int n = nums.size();
        vector<int> minvec,maxvec,outvec;
        long long res = 0;
        for(int i=0;i<n;i++){
            if(nums[i]<minK || nums[i]>maxK){
                outvec.push_back(i);
                minvec.clear();
                maxvec.clear();
                continue;
            }
            if(nums[i] == minK) {
                minvec.push_back(i);
            }
            if(nums[i] == maxK) {
                maxvec.push_back(i);
            }
            if(minvec.empty() || maxvec.empty()) continue;
            int x = outvec.empty()?-1:outvec.back();
            int u = min(minvec.back(), maxvec.back());
            // cout<<i<<' '<<u-x<<endl;
            res += u-x;

        }
        return res;

    }
};

偷学代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class Solution {
public:
    long long countSubarrays(vector<int> &nums, int min_k, int max_k) {
        long long ans = 0L;
        int n = nums.size(), min_i = -1, max_i = -1, i0 = -1;
        for (int i = 0; i < n; ++i) {
            int x = nums[i];
            if (x == min_k) min_i = i;
            if (x == max_k) max_i = i;
            if (x < min_k || x > max_k) i0 = i; // 子数组不能包含 nums[i0]
            ans += max(min(min_i, max_i) - i0, 0);
        }
        return ans;
    }
};
Licensed under CC BY-NC-SA 4.0
Built with Hugo
Theme Stack designed by Jimmy