【# 力扣35题,搜索插入位置详解】

文章详细解析了力扣第35题,即如何在一个升序排列且无重复元素的数组中,通过二分查找算法寻找目标值的插入位置。代码以C语言实现,重点解释了二分查找的逻辑,包括如何处理目标值在数组左侧和右侧的情况。文章还提供了运行示例及对输入处理的注意事项。
摘要由CSDN通过智能技术生成

力扣35题,搜索插入位置详解

题目;

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

请必须使用时间复杂度为 O(log n) 的算法。
示例 1:

输入: nums = [1,3,5,6], target = 5
输出: 2
示例 2:

输入: nums = [1,3,5,6], target = 2
输出: 1
示例 3:

输入: nums = [1,3,5,6], target = 7
输出: 4

提示:
1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums 为 无重复元素 的 升序 排列数组
-104 <= target <= 104

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/search-insert-position
著作权归领扣网络所有。

题解代码

C语言代码

#include <stdio.h>
int main() {
    char nums[100];
    int i = 0, numsSize;
    do {
        scanf("%c", &nums[i]);
        i++;
    } while (nums[i - 1]!= '\n');
    numsSize = i - 1;
    char target;
    scanf("%c", &target);
    int left = 0, right = numsSize - 1, ans = numsSize;
    while (left <= right) {
        int mid = ((right - left) >> 1) + left;
        if (target <= nums[mid]) {
            ans = mid;
            right = mid - 1;
        } else {
            left = mid + 1;
        }
    }
    printf("%d", ans);
}
题目分析
  1. 本题的条件为输入一个排序数组,在提示中有,nums 为无重复元素升序 排列数组,所以我们要注意数组的排序和数组元素的长度范围。
  2. 实现的功能有两个,在输入目标值之后,其一,找到目标值返回下标,其二,找不到目标值,按升序排列插入进去,返回其位置的下标。
  3. 使用时间复杂度为 O(log n) 的算法,小白可以理解为代码中只用到了一个循环,想多了解的同学可以看链接。
    链接: link

思路详解

1.输入部分
在力扣中没有输入部分,升序的数组是给定的,
直接拿来用就完事了,起初我在网络上找了好多资料,但是想要在自己的编译器上输入时按示例那样,且能让编译器正确接收到你的数据,难度还是有点的,我目前水平还做不到,后期水平足够的时候再出一篇关于输入的文章吧
输入时用一个do{ scanf(“%c”, &nums[i]);} while (nums[i - 1] != ‘\n’),把数组元素转为字符,依次输入进数组直至遇到换行符号。
2.为主函数的准备部分
numsSize = i - 1;/数组长度赋值/
char target; /这两行以字符形式输入目标值/
scanf(“%c”, &target);
int left = 0, right = numsSize - 1, ans = numsSize;/二分法备战了/
/左右端的下标,数组下标的长度/
3.小白入门必须先拿下的
二分法
在这里插入图片描述
纯手工打造的陋图
正式的二分法哈
while (left <= right) ----- 可以理解为两指针指向同一个数组元素时跳出
int mid = ((right - left) >> 1) + left;----这一坨通过运算得出中值,重点来了
右移运算符>>,
运算结果正好能对应一个整数的二分之一值,这就正好能代替数学上的除2运算,但是比除2运算要快。
mid=((right-left)>>1相当于mid=((right-left)/2

轻松理解mid=(right-left)>>1相当于mid=(right-left)/2

“<<”是二进制右移(位运算)
“<<1”相当于除了个2 ,
举个栗子;
二进制1010十进制10;
二进制0101十进制5;
1010 >> 1 == 0101;
所以 left + ((right -left) >> 1) ==> left + ((right -left)/2)
==> left + right/2 -left/2 ==> left/2 + right/2 ==> (left + right) /2
我们为什么要用这一步呢?
是因为left + right 在某种情况下可能会超过基本类型所能容纳的最大值,而且 >> (位运算) 比 / 运算要快一点
原文链接
链接: link

然后看这一段
找到目标值就跳出,没有找到有两种情况
一,目标值在区间左边,right=mid-1;把中值赋给右端。
二,目标值在区间右边,left = mid + 1;把中值赋给左端。
最后输出ans即可。

if (target <= nums[mid]) {
            ans = mid;
            right = mid - 1;
        } else {
            left = mid + 1;
        }
运行效果图

输入在数组中的输入值
目标值不存在于数组中,返回它将会被按顺序插入的位置
输入不在数组中的输入值
在这里插入图片描述

感悟

力扣是一个锻炼编程能力的网站,主要针对主函数,多数编程类比赛的考题模式跟力扣的编码模式不同,需要自己输入数组包括头文件等元素,自己可以单独锻炼,但是编程类比赛主要考的是思维逻辑等专业能力,不会再输入输出上为难你,再力扣上的训练重心要摆正,加油,每天学会一道题

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值