前言
目前准备每天刷一道题leetcode的题目,以此来激励那些零基础入门的人,千万不要被什么科班和非科班的说法吓倒了,计算机这个行业只要你肯努力,没有什么逾越不了的鸿沟。
只要你肯努力,一份努力,一份汗水,在程序员这个职业,你的每一份付出都会得到对应的那一份汇报,尊重学习规律,循序渐进,别想着一口吃个胖子,罗马也不是一天建成的,有朝一日,你终会变成你想成为的人。
题目目前可能需要一定的算法与数据结构基础才能看懂,后序会写一下零基础也能看懂的入门知识,然后就可以看懂我编写的题目了~
题目
leetcode-35 搜索插入的位置
分类(tag):二分查找的这一类
链接:
https://leetcode.com/problems/search-insert-position/
题目详述
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
示例 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
题目详解
不多BB,先上代码。
class Solution {
public int searchInsert(int[] nums, int target) {
if(nums.length == 0)
return 0;
if(nums.length == 1)
{
if(target <= nums[0])
return 0;
return 1;
}
int left = 0;
int right = nums.length - 1;
while(left <= right)
{
if(left == right)
{
if(nums[left] == target)
return left;
break;
}
int mid = left + (right - left) / 2;
if(nums[mid] == target)
{
return mid;
}else if(nums[mid] > target)
{
right = mid - 1;
}else{
left = mid + 1;
}
}
if(nums[left] > target)
return left;
return left+1;
}
}
思路:由于数组是有序的且没有重复的数字,对于有序和数组这两个字眼结合起来就是二分查找,然后如果找到的话直接返回下标的位置,如果没有找到,那么这时候由于left和right的下标相等,只需要在比较nums[left] 与target的值来觉得target往哪里插入。
代码详解
3-4行代码就是如果数组为空,那么直接插入这个数,下标是0;
5-9行就是如果数组只有一个数,那么比较target与nums[0],target如果比nums[0]小,那么target插入位置就是0,如果比nums[0]大,那么应该是1;
13行-31行就是二分查找的思想很简单,其中说一下15行到20行,15行中如果left与right相等了,那么说明查找过程已经要结束了!left与right进行了长征的会师,这个时候如果nums[left] 与target相等,那么直接返回下标left即可,如果不想等,那么break掉,退出这个循环。
接下来就是确定target需要插入到哪里。
这里举个例子[1,3,5,7],target是2.
如果left指向1,mid指向3,right指向7,
left数组下标是0,right是3,所以数组下标mid=(0+3)/2=1;
nums[mid]大于target,所以right=mid-1;
这个时候right就等于right=1-1=left ,所以这时候left与right相等,也就是代码15行,进入发现nums[left]与target不相等,退出循环;
然后这个时候就是去比较nums[left]与target的大小,如果nums[left]比target小,如果target是2,那么就说明target应该插入到left的后面,也就是left+1这个位置;如果target比nums[left]小,那么说明target应该插入到nums[left]前一个位置,因为插入到了left的前一个位置,left的下标就增长了1,所以target的下标就应该是left。也就是代码32-34行所示。
结束语
今天就是一个简单的二分查找的一个小小的变形,有一点点的难点感觉就是在确定target的位置的时候,需要小心一些。
END