首页 > 其他分享 >LeetCode刷题记录.Day1

LeetCode刷题记录.Day1

时间:2022-10-30 23:55:05浏览次数:124  
标签:right target nums int Day1 middle left LeetCode 刷题

二分查找基础:

二分查找

题目链接 Loading Question... - 力扣(LeetCode)

最开始的题解:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0 ;
        int right = nums.size() ;
        if (left < right){
            while(left < right){
                int middle = (left + right) / 2 ;
                if(nums[middle] > target){
                    right = middle ;
                }
                else if(nums[middle] < target){
                    left = middle ;
                }
                else if(nums[middle] == target){
                    return middle ;
                }
            }
            return -1 ;
        }
        else{
            return -1 ;
        }

    }
};

提交结果是超出时间限制。

在本地调试执行后发现是对边界理解有问题。左右边界在此时必不会有 = middle的情况,本来搜索范围在闭区间里,实际上我的循环更新边界,更新后的边界都在区间外,更新后的区间实际上是个开区间,但是循环条件确是闭区间。所以肯定会死循环。

我这种写法会导致如果target为数组中缺失数,出现middle不为整数的情况,导致进入死循环,所以超出时间限制。

 修改后

 

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0 ;
        int right = nums.size() - 1 ;
        if (target > nums[right] || target < nums[left]){
            return -1 ;
        }
        if (left <= right){
            while(left <= right){
                int middle = left + (right - left) / 2 ;
                if(nums[middle] > target){
                    right = middle - 1;
                }
                else if(nums[middle] < target){
                    left = middle + 1;
                }
                else if(nums[middle] == target){
                    return middle ;
                }
                else {
                    return -1 ;
                }
            }
            return -1 ;
        }
        else{
            return -1 ;
        }

    }
};

考虑了题目情况,数组为顺序排列。如果target大于数组边界值或小于数组边界值,可以直接返回 -1而不用进行二分查找。

最后根据标准解题方法过了一遍。

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0 ;
        int right = nums.size() - 1 ;
        while(left <= right){
            int middle = left + (right - left) / 2;
            if(target > nums[middle]){
                left = middle + 1;
            }
            else if(target < nums[middle]){
                right = middle - 1;
            }
            else{
                return middle;
            }
        }
        return -1;

    }
};

 个人理解的重点在边界条件判断,不管是循环条件还是更新区间,必须符合区间定义。称之为循环不变量。

搜索插入位置

题目链接 35. 搜索插入位置 - 力扣(LeetCode)

    int search(vector<int>& nums, int target) {
        int left = 0 ;
        int right = nums.size() - 1 ;
        if (target <= nums[left])
        {
            return left ;
        }
        if (target > nums[right]){
            return right + 1 ;
        }
        else if (target == nums[right])
        {
            return right ;
        }
        

        

        while(left <= right){
            int middle = left + (right - left) / 2 ;
            if(nums[middle] > target){
                right = middle - 1;
            }
            else if(nums[middle] < target){
                left = middle + 1;
            }
            else if(nums[middle] == target){
                return middle ;
            }
        }
        return left ;

    }

主要重点在于理解边界条件的判断。我这个写法有点冗余了.

 

在排序数组中查找元素的第一个和最后一个位置

题目链接 34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode)

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        int leftBorder = getLeftRange(nums, target);
        int rightBorder = getRightRange(nums, target);
        if (leftBorder == -2 || rightBorder == -2) return {-1,-1};
        if (rightBorder - leftBorder > 1) return {leftBorder + 1, rightBorder - 1};
        return {-1, -1};
    }
private:
    int getLeftRange(vector<int>& nums, int target) {
        int left = 0 ;
        int right = nums.size() - 1 ;
        int leftBorder = -2 ;
        while(left <= right){
            int middle = left + (right - left) / 2 ;
            if(nums[middle] >= target){
                right = middle - 1;
                leftBorder = right;
            }
            else{
                left = middle + 1;
            }
        }
        return leftBorder;
 
    }

    int getRightRange(vector<int>& nums, int target) {
        int left = 0 ;
        int right = nums.size() - 1 ;
        int rightBorder = -2 ;
        while(left <= right){
            int middle = left + (right - left) / 2 ;
            if(nums[middle] > target){
                right = middle - 1;
            }
            else{
                left = middle + 1;
                rightBorder = left;
            }
        }
        return rightBorder;
    }
};

修改出来的标准写法。不过还是没有理解为什么要这样去找左右边界。需要下来继续研究吃透这题的原理。

标签:right,target,nums,int,Day1,middle,left,LeetCode,刷题
From: https://www.cnblogs.com/tianmaster/p/16842194.html

相关文章

  • 刷题
    代码随想录LeetCode104. 二叉树的最大深度carl递归#二叉树遍历#层序遍历#队列#广度优先思路递归层序遍历细节略LeetCode111. 二叉树的最小深度思路......
  • LeetCode15. 三数之和
    题意找出数组中三个和为0的数字方法哈希表代码classSolution{public:vector<vector<int>>threeSum(vector<int>&nums){vector<vector<int>>resu......
  • 【HDLBits刷题笔记】10 Counters
    Count15moduletop_module(inputclk,inputreset,//Synchronousactive-highresetoutput[3:0]q);always@(posedgeclk)begin......
  • Leetcode第784题:字母大小写的全排列(Letters case permutation)
    解题思路使用回溯法。从左往右依次遍历字符,当遍历到字符串s的第i个字符c时:如果c为一个数字,继续检测下一个字符。如果c为一个字母,将其进行大小写转换,然后往后继续遍历;完......
  • 六六力扣刷题双指针之三数之和
    前言之前小六六一直觉得自己的算法比较菜,算是一个短板吧,以前刷题也还真是三天打鱼,两天晒网,刷几天,然后就慢慢的不坚持了,所以这次,借助平台的活动,打算慢慢的开始开刷,并且自己还......
  • 六六力扣刷题双指针之链表相交
    前言之前小六六一直觉得自己的算法比较菜,算是一个短板吧,以前刷题也还真是三天打鱼,两天晒网,刷几天,然后就慢慢的不坚持了,所以这次,借助平台的活动,打算慢慢的开始开刷,并且自己还......
  • Leetcode: 俩球之间的磁力
    题目在代号为C-137的地球上,Rick发现如果他将两个球放在他新发明的篮子里,它们之间会形成特殊形式的磁力。Rick有 n 个空的篮子,第 i 个篮子的位置在 position[i] ,Mo......
  • Leetcode 6233 -- dfs序
    题目描述给定我们一棵树,和一组查询,每个查询给出一个节点,让我们求删除以这个节点为根(包括这个节点)的子树中的所有节点之后(并不是真的删除),剩下的树中节点的最大高度。(树的......
  • leetcode-989-easy
    AddtoArray-FormofIntegerThearray-formofanintegernumisanarrayrepresentingitsdigitsinlefttorightorder.Forexample,fornum=1321,thearr......
  • leetcode 第90场双周赛
    6226.摧毁一系列目标题意:对于数组中每一个数nums[i],可以摧毁数组中值等于nums[i]+c*space的数(c为非负整数),求摧毁最大数量时的最小nums[i]思路:如果两个数x,y可以同时被摧......