【经典算法】LeetCode 35. 搜索插入位置(Java/C/Python3/Golang实现含注释说明,Easy)

简介: 【经典算法】LeetCode 35. 搜索插入位置(Java/C/Python3/Golang实现含注释说明,Easy)

题目描述

给定一个排序数组和一个目标值,在数组中找到目标值,如果找不到则返回可以将其插入的位置以保证数组仍然有序。

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

示例 1:

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

示例 2:

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

示例 3:

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

示例 4:

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

原题:力扣 35. 搜索插入位置

思路及实现

方式一:二分查找

思路

题目要求在一个有序数组中查找目标值,如果找不到则返回可以将其插入的位置以保证数组仍然有序。由于数组是有序的,所以我们可以使用二分查找算法来优化搜索过程。

二分查找的基本思路是,每次取数组的中间元素与目标值进行比较:

  • 如果中间元素正好是要查找的目标值,则搜索结束;
  • 如果目标值大于或小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。

在二分查找的过程中,我们可以同时记录可以插入目标值的位置。如果目标值大于中间元素,说明目标值应该插入在右半部分的起始位置,这个位置正好是中间元素的下一个位置;如果目标值小于中间元素,说明目标值应该插入在左半部分的末尾位置,这个位置正好是中间元素的位置。

代码实现

Java版本
public class Solution {
    public int searchInsert(int[] nums, int target) {
        int left = 0, right = nums.length - 1;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] == target) {
                return mid;
            } else if (nums[mid] < target) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        // 退出循环时,left > right,left 的位置就是可以插入 target 的位置
        return left;
    }
}

说明:

Java版本的实现中,我们定义了两个指针leftright,分别表示数组的起始位置和结束位置。在while循环中,我们计算中间位置mid,并根据nums[mid]与目标值target的比较结果来更新leftright的值。最终,当循环结束时,left的值就是可以插入target的位置。

C语言版本
int searchInsert(int* nums, int numsSize, int target) {
    int left = 0, right = numsSize - 1;
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] == target) {
            return mid;
        } else if (nums[mid] < target) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return left;
}

说明:

C语言版本的实现与Java版本类似,但是需要注意在C语言中,数组的大小需要作为函数的参数传递。

Python3版本
class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        left, right = 0, len(nums) - 1
        while left <= right:
            mid = (left + right) // 2
            if nums[mid] == target:
                return mid
            elif nums[mid] < target:
                left = mid + 1
            else:
                right = mid - 1
        return left

说明:

Python3版本的实现也采用了二分查找的思路,并且使用了整数除法//来避免浮点数。

Golang版本
package main
import "fmt"
func searchInsert(nums []int, target int) int {
    left, right := 0, len(nums)-1
    for left <= right {
        mid := left + (right-left)/2
        if nums[mid] ==target {
            return mid
        } else if nums[mid] < target {
            left = mid + 1
        } else {
            right = mid - 1
        }
    }
    return left
}
func main() {
    nums := []int{1, 3, 5, 6}
    target := 5
    result := searchInsert(nums, target)
    fmt.Println(result) // 输出: 2
}

说明:

Golang版本的实现与前面几种语言类似,同样使用了二分查找算法来寻找目标值或者插入位置。

复杂度分析

  • 时间复杂度:O(log n),其中 n 是数组的长度。二分查找每次都将搜索范围减半,因此时间复杂度是对数级别的。
  • 空间复杂度:O(1)。我们只使用了常量级别的额外空间来存储指针和中间变量。

方式二:线性搜索

思路

虽然题目中给出了数组是有序的,但我们也可以使用线性搜索(即遍历数组)的方式来解决问题。对于每个数组元素,我们比较它是否等于目标值,或者是否小于目标值以确定插入位置。

代码实现

Java版本
public class Solution {
    public int searchInsert(int[] nums, int target) {
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] >= target) {
                return i;
            }
        }
        // 如果遍历完整个数组都没有找到目标值,说明目标值应该插入在数组末尾
        return nums.length;
    }
}

说明:

Java版本的实现中,我们遍历数组,一旦找到某个元素大于等于目标值,就返回当前位置。如果遍历完整个数组都没有找到,则返回数组长度,表示目标值应该插入在数组末尾。

C语言版本
int searchInsert(int* nums, int numsSize, int target) {
    for (int i = 0; i < numsSize; i++) {
        if (nums[i] >= target) {
            return i;
        }
    }
    return numsSize;
}

说明:

C语言版本的实现与Java版本类似,但是需要注意在C语言中,数组的大小是作为函数的参数传递的。

Python3版本
class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        for i in range(len(nums)):
            if nums[i] >= target:
                return i
        return len(nums)

说明:

Python3版本使用for循环遍历数组,一旦找到大于等于目标值的元素,就返回其索引。

Golang版本
package main
import "fmt"
func searchInsert(nums []int, target int) int {
    for i, num := range nums {
        if num >= target {
            return i
        }
    }
    return len(nums)
}
func main() {
    nums := []int{1, 3, 5, 6}
    target := 5
    result := searchInsert(nums, target)
    fmt.Println(result) // 输出: 2
}

说明:

Golang版本的实现使用range关键字遍历数组,与Python3版本类似。

复杂度分析

  • 时间复杂度:O(n),其中 n 是数组的长度。在最坏情况下,我们需要遍历整个数组才能找到插入位置。
  • 空间复杂度:O(1)。我们同样只使用了常量级别的额外空间来存储索引和中间变量。

总结

方式 优点 缺点 时间复杂度 空间复杂度
方式一(二分查找) 效率高,时间复杂度低 需要数组有序 O(log n) O(1)
方式二(线性搜索) 代码简单,容易理解 时间复杂度较高 O(n) O(1)

相似题目

相似题目 难度 链接
leetcode 34. 在排序数组中查找元素的第一个和最后一个位置 中等 力扣-34
相关文章
|
3月前
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
101 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
|
3月前
|
算法
Leetcode 初级算法 --- 数组篇
Leetcode 初级算法 --- 数组篇
48 0
|
2月前
|
Python
二分查找变种大赏!Python 中那些让你效率翻倍的搜索绝技!
二分查找是一种高效的搜索算法,适用于有序数组。其基本原理是通过不断比较中间元素来缩小搜索范围,从而快速找到目标值。常见的变种包括查找第一个等于目标值的元素、最后一个等于目标值的元素、第一个大于等于目标值的元素等。这些变种在实际应用中能够显著提高搜索效率,适用于各种复杂场景。
43 9
|
2月前
|
算法 数据处理 开发者
超越传统:Python二分查找的变种策略,让搜索效率再上新台阶!
本文介绍了二分查找及其几种Python实现的变种策略,包括经典二分查找、查找第一个等于给定值的元素、查找最后一个等于给定值的元素以及旋转有序数组的搜索。通过调整搜索条件和边界处理,这些变种策略能够适应更复杂的搜索场景,提升搜索效率和应用灵活性。
39 5
|
2月前
|
存储 算法 Java
leetcode算法题-有效的括号(简单)
【11月更文挑战第5天】本文介绍了 LeetCode 上“有效的括号”这道题的解法。题目要求判断一个只包含括号字符的字符串是否有效。有效字符串需满足左括号必须用相同类型的右括号闭合,并且左括号必须以正确的顺序闭合。解题思路是使用栈数据结构,遍历字符串时将左括号压入栈中,遇到右括号时检查栈顶元素是否匹配。最后根据栈是否为空来判断字符串中的括号是否有效。示例代码包括 Python 和 Java 版本。
|
3月前
|
算法
每日一道算法题(Leetcode 20)
每日一道算法题(Leetcode 20)
36 2
|
3月前
|
算法 Java 数据中心
探讨面试常见问题雪花算法、时钟回拨问题,java中优雅的实现方式
【10月更文挑战第2天】在大数据量系统中,分布式ID生成是一个关键问题。为了保证在分布式环境下生成的ID唯一、有序且高效,业界提出了多种解决方案,其中雪花算法(Snowflake Algorithm)是一种广泛应用的分布式ID生成算法。本文将详细介绍雪花算法的原理、实现及其处理时钟回拨问题的方法,并提供Java代码示例。
98 2
|
4月前
|
大数据 UED 开发者
实战演练:利用Python的Trie树优化搜索算法,性能飙升不是梦!
在数据密集型应用中,高效搜索算法至关重要。Trie树(前缀树/字典树)通过优化字符串处理和搜索效率成为理想选择。本文通过Python实战演示Trie树构建与应用,显著提升搜索性能。Trie树利用公共前缀减少查询时间,支持快速插入、删除和搜索。以下为简单示例代码,展示如何构建及使用Trie树进行搜索与前缀匹配,适用于自动补全、拼写检查等场景,助力提升应用性能与用户体验。
73 2
|
3月前
|
Python
【python从入门到精通】-- 第二战:注释和有关量的解释
【python从入门到精通】-- 第二战:注释和有关量的解释
58 0
|
3月前
|
数据采集 前端开发 Python
Python pygame 实现游戏 彩色 五子棋 详细注释 附源码 单机版
Python pygame 实现游戏 彩色 五子棋 详细注释 附源码 单机版
97 0