• c++入门99题51-60


    解题报告

    1.力扣167

    原题链接

    167. 两数之和 II - 输入有序数组

    源码剖析

    class Solution {
    public:
        vector<int> twoSum(vector<int>& numbers, int target) {
            vector<int> ans;
            int l = 0,r = numbers.size()-1;
            while(l<r){
                if(numbers[l]+numbers[r]==target){
                    return {l+1,r+1};
                }
                if(numbers[l]+numbers[r]>target){
                    r--;
                    continue;
                }else if(numbers[l]+numbers[r]<target){
                    l++;
                    continue;
                }
            }
            return {l+1,r+1};
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    和上一道题是一样的,不过这里最终返回的下标要全都加一。

    2.力扣933

    原题链接

    933. 最近的请求次数

    源码剖析

    class RecentCounter {
        queue<int> q;
    public:
        RecentCounter() {
            
        }
        int ping(int t) {
            while(!(q.empty())){
                if(t-q.front()>3000){
                    q.pop();
                }else break;
            }
            q.push(t);
            return q.size();
        }
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    直接使用stl创建一个队列,然后初始化就不需要了。由于当前队列内所记录的都是上一次操作的时间 t 。因此队首的元素就是最早进入的,也就是 t 为最小的,那么如果要求返回的申请数是最近3000ms内的,只需要将最新申请的时间与队首的元素进行比较,如果差小于3000ms就可以直接将新的申请入队然后返回队列长度也就是申请数,否则不断出队队首元素直到队首元素与 t 的差值小于3000ms为止。

    3.力扣剑指 Offer II 041. 滑动窗口的平均值

    原题链接

    剑指 Offer II 041. 滑动窗口的平均值

    源码剖析

    class MovingAverage {
        queue<int> q;
        int s,sum;
    public:
        /** Initialize your data structure here. */
        MovingAverage(int size) {
            s = size;
            sum  = 0;
        }
        
        double next(int val) {
            q.push(val);
            sum +=val;
            if(q.size()>s){
                sum -= q.front();
                q.pop();
            }
            return sum*1.0/q.size();
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    使用一个队列来辅助实现。初始化时,将代表着窗口长度的变量 s 赋值,并初始化队列内元素总和为 0;每次执行 next() 时,首先将元素入队,然后队列内元素总和加上入队的值,接下来再对队列的长度进行判断,如果队列的长度已经超过窗口长度了,那就先使得总和 sum 减去队首元素,然后使其出队。最后返回 sum 除上队列长度即可。

    4.力扣704

    原题链接

    704. 二分查找

    源码剖析

    class Solution {
    public:
        int search(vector<int>& nums, int target) {
            int l = 0,r = nums.size()-1;
            while(l<=r){
                int mid = (l+r)/2;
                if(nums[mid]==target){
                    return mid;
                }
                if(nums[mid]>target){
                    r = mid-1;
                    continue;
                }else{
                    l = mid+1;
                    continue;
                }
            }
            return -1;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    经典二分查找。

    解题报告

    5.力扣35

    原题链接

    35. 搜索插入位置

    源码剖析

    class Solution {
    public:
        int searchInsert(vector<int>& nums, int target) {
            int l = 0,r = nums.size()-1;
            int ans = r+1;
            while(l<=r){
                int mid = (l+r)/2;
                if(nums[mid]<target){
                    l = mid+1;
                    continue;
                }else{
                    ans = mid;
                    r = mid-1;
                    continue;
                }
            }
            return ans;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    此题的要求实际上是找到大于等于目标值 target 的最小下标。于是可以使用一个变量 ans 来记录需要返回的下标,然后此时二分的作用变为了不断的缩小范围,当 mid 处的元素小于 target 时就只缩小范围,而大于 target 时才去需要移动 ans 的位置。因此这里也有一个细节,ans 有可能会大于所有元素,所以初始值的位置应当是 nums.size()

    6.力扣69. x 的平方根

    原题链接

    69. x 的平方根

    源码剖析

    class Solution {
    public:
        int mySqrt(int x) {
            long long ans = 0;
            long long l = 0,r = INT_MAX;
            while(l<=r){
                long long mid = (l+r)/2;
                if(mid*mid<=x){
                    ans = mid;
                    l = mid+1;
                }else {
                    r = mid - 1;
                }
            }
            return ans;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    这题与上面一题恰好相反。

    7.力扣367

    原题链接

    367. 有效的完全平方数

    源码剖析

    class Solution {
    public:
        bool isPerfectSquare(int num) {
            long long l = 0, r = INT_MAX;
            while(l<=r){
                long long mid = (l+r)/2;
                if(mid*mid==num){
                    return true;
                }
                if(mid*mid<num){
                    l = mid + 1;
                    continue;
                }else{
                    r = mid - 1;
                    continue;
                }
            }
            return false;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    直接上普通的二分查找就可以了。

    8.力扣2236

    原题链接

    2236. 判断根结点是否等于子结点之和

    源码剖析

    class Solution {
    public:
        bool checkTree(TreeNode* root) {
            return root->val==root->right->val+root->left->val;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    白给。

    解题报告

    9.力扣1979

    原题链接

    1979. 找出数组的最大公约数

    源码剖析

    class Solution {
        int gcd(int a,int b){
            return b==0?a:gcd(b,a%b);
        }
    public:
        int findGCD(vector<int>& nums) {
            int maxv = 0,minv = 1001;
            for(int i = 0;i<nums.size();++i){
                maxv = max(maxv,nums[i]);
                minv = min(minv,nums[i]);
            }
            return gcd(maxv,minv);
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    使用递归辗转相除法对最大值和最小值求公因数即可。

    10.力扣2177

    原题链接

    2177. 找到和为给定整数的三个连续整数

    源码剖析

    class Solution {
    public:
        vector<long long> sumOfThree(long long num) {
            if(num%3){
                return {};
            }else{
                long long tmp = num/3;
                return {tmp-1,tmp,tmp+1};
            }
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    一道简单的数学题。

  • 相关阅读:
    新一代云数据库的引领者---AWS
    有人知道这个动作模型是哪里的吗?叫什么?
    开启可视化金融时代!菊风联合助推山东农信视频银行项目
    ESP8266 如何使用 GPIO13 & GPIO15 进行 UART0 通信?
    Promise的使用
    linux进程
    Qt界面容器:Widget、 Frame、分组框、滚动区、工具箱、选项卡小部件、堆叠小部件控件精讲
    记一次任意文件下载到Getshell
    分享Arduino环境下加速下载 第三方库或芯片包
    SOLIDWORKS® 2024 新功能 - 3D CAD
  • 原文地址:https://blog.csdn.net/smallwind256/article/details/126104352