• Leetcode-35. 搜索插入位置


    35. 搜索插入位置

    给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

    你可以假设数组中无重复元素。

    示例 1:

    输入: [1,3,5,6], 5
    输出: 2
    

    解法一

    可以顺序搜索查找,比当前大就往下遍历,比当前小就返回当前的index,最后返回数组长度(即插在最后一个index的后面)

    class Solution {
    public:
        int searchInsert(vector<int>& nums, int target) {
            for (int i = 0; i < nums.size(); ++i) {
                if (target > nums[i]) {
                    ;
                } else {
                    return i;
                }
            }
            return nums.size();
        }
    };
    

    解法二

    可以二分查找,但二分查找虽然时间复杂度低一些,但是中间需要考虑的边界条件多一些,有两个地方需要考虑

    • 搜索到边界时需要退出并返回边界(插在最后一个位置后面)。
    • 当搜索到的start和end相邻时,mid为start,如果此时nums[mid]<target,则正常逻辑start更新为mid,则导致无限循环。

    所以代码中需着重考虑这两点

    class Solution {
    public:
        int searchInsert(vector<int>& nums, int target) {
            int start = 0;
            int end = nums.size();
            while (start <= end) {
                int mid = (start + end) / 2;
                if (nums[mid] < target) {
                    if (start == mid) {
                        return end;
                    }
                    start = mid;
                } else if (nums[mid] > target) {
                    if (start == mid) {
                        return start;
                    }
                    end = mid;
                } else {
                    return mid;
                }
            }
            return start;
        }
    };
    

    但这样的思考显然过于复杂,写二分查找也不通用,所以看了一个题解后掌握了一个重要的思想:从一个元素什么时候不是解开始考虑下一轮搜索区间是什么,也就是要注意搜索区间。由于mid的范围为[start, end), 但是我们搜索区间的范围是[start, end], 所以一开始 start=0, end=nums.size(), 这样不用担心mid越界的问题,也包含了所有解的空间。之后每次更新区间都要注意这个范围的意义和前面保持一致。

    由于start和end都是根据mid来更新,所以mid不可能取到end,只有可能取到start。且由于mid的范围限制,循环时判断start == end时就应该退出并返回start。

    更新时如果nums[mid]<target,那么搜索区间肯定不包含mid之前包括mid的部分,最小也是mid+1,所以本着搜索区间应该是[start, end]的原则,start更新为mid+1。

    反之如果 nums[mid]>target,那么搜索区间有可能包含mid,所以end更新为mid。

    如果相等,则返回mid即可。

    class Solution {
    public:
        int searchInsert(vector<int>& nums, int target) {
            int start = 0;
            int end = nums.size();
            while (start != end) {
                int mid = (start + end) / 2;
                if (nums[mid] < target) {
                    start = mid + 1;
                } else if (nums[mid] > target) {
                    end = mid;
                } else {
                    return mid;
                }
            }
            return start;
        }
    };
    
  • 相关阅读:
    一道百度2014校招笔试题
    leetcode_question_119 Pascal's Triangle II
    STL 查找vector容器中的指定对象:find()与find_if()算法
    QT类的继承结构
    poj 3254 Corn Fields (状态压缩DP)
    从vector容器中查找一个子串:search()算法
    linux 提示符绝对路径
    ssh加密公私钥
    yum-plugin-priroites这个插件的一个文件。
    什么是EPEL 及 Centos上安装EPEL
  • 原文地址:https://www.cnblogs.com/eggplant-is-me/p/13984661.html
Copyright © 2020-2023  润新知