Open azl397985856 opened 3 years ago
二分法
public int searchInsert(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if(nums[mid] == target){
return mid;
}
if(nums[mid] > target) {
right = mid - 1;
}else {
left = mid + 1;
}
}
return left;
}
二分法
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
left=0
right=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
T: O(logN) S: O(1)
class Solution {
public int searchInsert(int[] nums, int target) {
int l = 0, r = nums.length - 1;
while (l <= r) {
int mid = l + (r - l) / 2;
if (nums[mid] < target) {
// 4 5 6 we are at 5, target = 7
// go to right part;
l = mid + 1;
} else if (nums[mid] >= target) {
r = mid - 1;
}
}
return l;
}
}
TC: O(log N)
SC: O(1)
class Solution {
public int searchInsert(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while( left + 1 < right) {
//这道题没必要
int mid = left + (right - left) / 2;
if (nums[mid] < target) {
left = mid;
} else if (nums[mid] > target) {
right = mid;
} else {
return mid;
}
}
if (nums[left] >= target) {
return left;
} else if (nums[right] >= target) {
return right;
}
return right + 1;
}
}
模板题:寻找最左插入位置
def bisect_left(nums,x):
l = bisect.bisect_left(nums,x)
l, r = 0, len(nums)-1
while l <= r:
mid = (l+r)>>1
if nums[mid] > x: r = mid - 1
elif nums[mid] == x: r = mid -1
elif nums[mid] < x: l = mid + 1
return l
time complexity : O(logn) space complexity: O(1)
经典二分查找题。 移动左右指针来判断target 和nums[mid] 大小再移动指针
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
left,right = 0, len(nums)-1
while left <= right:
mid = left + (right-left)//2
if nums[mid] == target:
return mid
elif nums[mid] > target:
right = mid-1
else:
left = mid + 1
return left
Time complexity: O(logN) Space complexity: O(1)
二分法
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
if not nums:
return 0
start, end = 0,len(nums)-1
while start<=end:
mid = (end+start)//2
if nums[mid] == target:
return mid
elif nums[mid]<target:
start = mid+1
else:
end = mid-1
return start
复杂度分析
二分法
function searchInsert(nums: number[], target: number): number {
const len = nums.length
let l = 0, r = len - 1, ans = len;
while (l <= r) {
const mid = l + ((r - l) >> 1);
if (target <= nums[mid]) {
ans = mid;
r = mid - 1;
} else {
l = mid + 1;
}
}
return ans;
};
var searchInsert = function(nums, target) {
let left=0,right=nums.length;
function search(left,right,nums){
if(right===left)return left;
let mid=(right+left)>>1;
if(target>nums[mid]){
return search(mid+1,right,nums)
}else if(target<nums[mid]){
return search(left,mid,nums)
}else{
return mid
}
}
return search(left,right,nums)
};
双指针二分法遍历
Python3 Code:
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
length = len(nums)
if target > nums[-1]: return length
left = 0
right = length-1
while left <= right:
mid = (right+left)//2
if nums[mid]>target:
right = mid - 1
elif nums[mid]<target:
left = mid + 1
else:
return mid
return left
复杂度分析
令 n 为数组长度。
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 # return index
elif nums[mid] > target:
right = mid - 1
else:
left = mid + 1
return left
time O: logn space O: 1
二分查找
var searchInsert = function (nums, target) {
let l = 0, r = nums.length - 1;
while (l <= r) {
mid = Math.floor((l + r) / 2)
if (target <= nums[mid]) r = mid - 1
else l = mid + 1
}
return l
};
令 n 为数组长度
时间复杂度:$O(logn)$ 空间复杂度:$O(1)$
class Solution {
public int searchInsert(int[] nums, int target) {
int n = nums.length;
int left = 0, right = n - 1, ans = n;
while (left <= right) {
int mid = ((right - left) >> 1) + left;
if (target <= nums[mid]) {
ans = mid;
right = mid - 1;
} else {
left = mid + 1;
}
}
return ans;
}
}
二分查找
Javascript Code
var searchInsert = function (nums, target) {
for (let i = 0; i < nums.length; i++) {
if (nums[i] >= target) {
return i;
}
}
return nums.length;
};
复杂度
套用二分法模板
语言:Java
class Solution {
public int searchInsert(int[] nums, int target) {
if(nums==null) {
return 0;
}
int left=0,right=nums.length-1;
while(left<=right) {
int mid=(left+right)/2;
if(nums[mid]==target) {
return mid;
}else if(nums[mid]>target) {
right=mid-1;
}else {
left=mid+1;
}
}
return left;
}
}
二分
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int n = nums.size();
int left = 0;
int right = n - 1;
while(left <= right){
int mid = left + ((right - left) / 2);
if(nums[mid] < target){
left = mid + 1;
}else if(nums[mid] > target){
right = mid - 1;
}else{
return mid;
}
}
return right + 1;
}
};
时间复杂度:O(logn)
空间复杂度:O(1)
class Solution:
def Healper(self, nums, start, end, target):
mid = (start + end)//2
if nums[mid] == target:
return mid
if start == end:
if target <= nums[start]:
return start
elif target > nums[start]:
return start + 1
if target > nums[mid]:
return self.Healper(nums, mid+1, end, target)
if target < nums[mid]:
return self.Healper(nums, start, mid, target)
def searchInsert(self, nums: List[int], target: int) -> int:
return self.Healper(nums, 0, len(nums)-1, target)
time space O(logn)
暴力破解,考虑4种情况:
a. 数组长度0时,直接返回0
b. 添加值比数组中的最小值还小的情况,或者比数组中最大值还大的情况
c. 中间比前一个小后一个大的情况
d. 能找到的情况
二分法,关于题目要考虑的东西都一样,只是在遍历的方式上,将时间复杂度从O(n)降低为O(logn)
对于二分法要注意的就是临界问题考虑
// 暴力破解
class Solution {
public int searchInsert(int[] nums, int target) {
// 长度为0不会进循环,所有都比目标值小惠遍历完,最后都直接返回数组长度值的位置,实现ab情况
// 因为是排好序的,故第一个大于目标值的位置就是要添加的地方,用 <= 实现cd情况
for(int i = 0; i < nums.length; i++){
if(nums[i] >= target){
return i;
}
}
return nums.length;
}
}
// 二分法
class Solution {
public int searchInsert(int[] nums, int target) {
if(nums.length == 0){
return 0;
}
int left = 0;
int right = nums.length-1;
int temp;
while(true){
if(right - left <= 1){
if(nums[left] >= target){
return left;
}
if(nums[right] >= target){
return right;
}
return right + 1;
}
// 取中间值,与目标值对比,小就左指针,大就右指针
temp = (right+left)/2;
if(nums[temp] == target){
return temp;
}
if(nums[temp] > target){
right = temp;
}
if(nums[temp] < target){
left = temp;
}
}
}
}
复杂度分析
— 时间复杂度:暴力O(n),二分法O(logn),其中n为数组长度。
— 空间复杂度:O(1)
Java Code:
class Solution {
public int searchInsert(int[] nums, int target) {
int len=nums.length;
int i=0;
int j=len-1;
while(i<j){
int mid=i+(j-i)/2;
if(nums[mid]==target)return mid;
if(target<nums[mid])j=mid-1;
else{
i=mid+1;
}
}
if(target<=nums[i])return i;
//else if(target==nums[i])return
else return i+1;
}
}
title: "Day 27 35. 搜索插入位置" date: 2021-10-06T15:30:50+08:00 tags: ["Leetcode", "c++", "二分查找"] categories: ["algorithm"] draft: true
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 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
示例 4:
输入: nums = [1,3,5,6], target = 0
输出: 0
示例 5:
输入: nums = [1], target = 0
输出: 0
提示:
1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums 为无重复元素的升序排列数组
-104 <= target <= 104
- 1、修改二分法模板的题目,
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int n = nums.size();
int l = 0, r = n - 1;
int mid = 0;
while(l <= r)
{
mid = l + (r - l) / 1;
if(nums[mid] == target) return mid;
else if(nums[mid] > target) r = mid - 1;
else l = mid + 1;
}
return l == mid + 1 ? l : mid;
}
};
时间复杂度:O(logn)
空间复杂度:O(1)
二分法 把问题等价于找到第一个大于等于这个数
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
"""
classic binary search
"""
if not nums:
return 0
start, end = 0, len(nums)-1
while start <= end:
mid = (start + end) // 2
if nums[mid] < target:
start = mid + 1
elif nums[mid] > target:
end = mid - 1
else:
return mid
return start
complexity 时间复杂度O(lgn)
空间复杂度O(1)
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
left, right = 0, len(nums) - 1
while left <= right:
mid_idx = (left + right) >> 1
if target == nums[mid_idx]:
return mid_idx
# right part
if target > nums[mid_idx]:
left = mid_idx + 1
# left part
if target < nums[mid_idx]:
right = mid_idx - 1
return left
Time: O (log N)
Space: O (1)
二分、需要注意的是我们要 l<=r、因为可能会出现 target 比最后一个数还要大的情况
var searchInsert = function(nums, target) {
let l = 0
let r = nums.length-1
while(l<=r){
const mid = l+((r-l)>>1)
let num = nums[mid]
if(num==target){
return mid
}else if(num<target){
l =mid + 1
}else{
r = mid-1
}
}
return l
};
二分法
class Solution(object):
def searchInsert(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
left = 0
right = 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
思路:用二分法
操作:定义双指针 left 和 right 同向而行 找到就返回
code
public int SearchInsert(int[] nums, int target) {
int left = 0;
int right = nums.Length - 1;
while(left <= right)
{
int mid = left + (right - left>>1);
if(nums[mid] == target)
{
return mid;
}
else if(nums[mid] < target)
{
left = mid + 1;
}
else{
right = mid - 1;
}
}
return left;
}
二分查找
JavaScript Code
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var searchInsert = function(nums, target) {
let left = 0, right = nums.length - 1, res = nums.length;
while (left <= right) {
const mid = left + right >> 1;
if (nums[mid] >= target) {
right = mid - 1;
res = mid;
} else {
left = mid + 1;
}
}
return res;
};
时间复杂度:O(log n)
空间复杂度:O(1)
二分查找
class Solution {
public int searchInsert(int[] nums, int target) {
int n = nums.length;
int left = 0, right = n - 1, ans = n;
while (left <= right) {
int mid = ((right - left) >> 1) + left;
if (target <= nums[mid]) {
ans = mid;
right = mid - 1;
} else {
left = mid + 1;
}
}
return ans;
}
}
时间复杂度 O(log n)
空间复杂度 O(1)
Binary search.
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
left = 0
right = len(nums)
while left < right:
mid = (left + right) // 2
if nums[mid] > target:
right = mid
elif nums[mid] < target:
left = mid + 1
else:
return mid
return right
Time complexity: O(logn) Space complexity: O(1)
class Solution { public int searchInsert(int[] nums, int target) { int l = 0, r = nums.length; while(l < r) { int mid = (l + r) >> 1; if(nums[mid] < target) { l = mid + 1; } else { r = mid; } } return l; } }
二分查找
var searchInsert = function(nums, target) {
let left = 0, right = nums.length - 1;
while(left <= right) {
let mid = parseInt((left + right) / 2);
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return left;
};
35. 搜索插入位置
入选理由
暂无
题目地址
https://leetcode-cn.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
二分查找
class Solution: def searchInsert(self, nums: List[int], target: int) -> int: left=0 right=len(nums) while left<right: mid=(right+left)//2 if nums[mid]>target: right=mid elif nums[mid]<target: left=mid+1 else: return mid return left
时间复杂度:O(log(n)) 空间复杂度:O(1)
排序数组 二分法
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var searchInsert = function(nums, target) {
let l = 0,r = nums.length - 1
while(l <= r) {
let mid = (l + r) >> 1
if(nums[mid] === target) {
return mid
} else if (nums[mid] < target) {
l = mid + 1
} else {
r = mid - 1
}
}
return l
};
时间复杂度: O(logn)
空间复杂度: O(1)
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var searchInsert = function(nums, target) {
let left = 0, right = nums.length - 1, res = nums.length;
while (left <= right) {
let mid = (right + left) >> 1
if (target <= nums[mid]) {
res = mid;
right = mid - 1;
} else {
left = mid + 1;
}
}
return res;
};
二分法
``
class Solution {
public int searchInsert(int[] nums, int target) {
int len = nums.length;
if (len == 0) {
return 0;
}
int right = len -1;
int left = 0;
while (left <= right) {
int mid = left + ((right - left) >> 1);
if (nums[mid] == target) {
return mid;
} else if (nums[mid] > target) {
right = mid - 1;
} else if (nums[mid] < target) {
left = mid + 1;
}
}
return left;
}
}
时间复杂度:O(logn)
空间复杂度:O(1)
class Solution { public int searchInsert(int[] nums, int target) { int l = nums.length; int left = 0; int right = l-1; int ans = l; while(left<=right){ int mid = (right+left)/2; if(nums[mid]<target){ left = mid+1; } else{ right = mid-1; ans = mid; } } return ans; } }
二分法
var searchInsert = function(nums, target) {
let i = 0;
let n = nums.length-1;
let res = nums.length;
while(i<=n){
const mid = Math.floor((n+i)/2);
if(nums[mid]>=target){
res = mid;
n=mid-1;
}else{
i=mid+1;
}
}
return res;
};
二分法
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
left = 0
right = len(nums) -1
while left <= right:
mid = (right-left) // 2 + left
if nums[mid] < target:
left = mid + 1
elif nums[mid] > target:
right = mid - 1
else:
return mid
return left
时间复杂度:O(LOGN)
空间复杂度:O(1)
二分法查找,快速定位
class Solution {
public int searchInsert(int[] nums, int target) {
int n = nums.length;
int left = 0, right = n - 1, ans = n;
while (left <= right) {
int mid = ((right - left) >> 1) + left;
if (target <= nums[mid]) {
ans = mid;
right = mid - 1;
} else {
left = mid + 1;
}
}
return ans;
}
}
class Solution {
public:
int searchInsert(vector<int>& nums, int target)
{
int left=0,right=nums.size()-1;
while(left<=right)
{
int mid=(right-left)/2+left;
if(nums[mid]<target) left=mid+1;
else if(nums[mid]>target) right=mid-1;
else
{
return mid;
}
}
return left;
}
};
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var searchInsert = function (nums, target) {
let left = 0,
right = nums.length - 1
if (target < nums[left]) {
return 0
}
if (target > nums[right]) {
return right + 1
}
while (left < right) {
let middle = (right + left) >> 1
if (target == nums[middle]) {
return middle
}
if (right - left == 1) {
return right
}
if (target > nums[middle]) {
left = middle
} else {
right = middle
}
}
return left
}
class Solution {
public int searchInsert(int[] nums, int target) {
int left = 0;
int 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;
}
}
return left;
}
}
有序数组+logn要求 标准的二分
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
l, r = 0, len(nums)-1
while l <= r:
mid = l + (r - l) // 2
if nums[mid] == target:
return mid
elif nums[mid] > target:
right = mid - 1
elif nums[mid] < target:
left = mid + 1
return left
nums contains distinct values sorted in ascending order.
# Logic:
Binary search, inclusive
Time: o(logn)
Space: O(1)
class Solution {
public int searchInsert(int[] nums, int target) {
int l = 0, r = nums.length - 1;
while (l <= r) {
int mid = l + (r - l) / 2;
if (nums[mid] > target) {
r = mid - 1;
} else if (nums[mid] < target) {
l = mid + 1;
} else {
return mid;
}
}
return l;
}
}
思路 利用二分法查找 代码
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int l = 0;
int r = nums.size();
while(l <= r)
{
const int mid = (l + r) >> 1;
const int midval = nums[mid];
if(midval == target)
{
return mid;
}
else if(midval < target)
{
l = midval + 1;
}
else{
r = midval - 1;
}
}
return l;
}
};
复杂度 时间复杂度:二分法O(logN) 空间复杂度:O(1)
int searchInsert(int* a, int numsSize, int target){
if(target > a[numsSize-1])
return numsSize;
else if(target < a[0])
return 0;
int low, high, mid;
low = 0;
high = numsSize-1;
mid = 0;
while(low < high)
{
mid = (low+high) / 2;
if(a[mid] == target)
return mid;
else if(a[mid] > target)
high = mid;
else
low = mid+1;
}
return low;
}
二分查找
class Solution {
public int searchInsert(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
int middle = left + (right - left) / 2;
if (nums[middle] == target) return left;
if (nums[middle] < target) left = middle + 1;
else right = middle - 1;
}
return left;
}
}
二分 class Solution { public int searchInsert(int[] nums, int target) { int left = 0; int right = nums.length - 1; while(left <= right){ int mid = right + (left - right)/2; if(nums[mid]==target){ return mid; } if(nums[mid] > target){ right = mid - 1; } if(nums[mid] < target){ left = mid + 1; } } return left; } }
二分法
var searchInsert = function(nums, target) {
const n = nums.length;
let left = 0, right = n - 1, ans = n;
while (left <= right) {
let mid = ((right - left) >> 1) + left;
if (target <= nums[mid]) {
ans = mid;
right = mid - 1;
} else {
left = mid + 1;
}
}
return ans;
};
var searchInsert = function(nums, target) {
const n = nums.length;
let left = 0, right = n - 1, ans = n;
while (left <= right) {
let mid = ((right - left) >> 1) + left;
if (target <= nums[mid]) {
ans = mid;
right = mid - 1;
} else {
left = mid + 1;
}
}
return ans;
};
二分法
C++ Code:
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int len = nums.size();
int ans = len;
if(target<nums[0])return 0;
if(target>nums[len - 1])return len;
int left = 0;
int right = len - 1;
while(left<=right){
int mid = (left + right)>>1;
if(nums[mid]>=target){
ans = mid;
right = mid - 1;
}
else {
left = mid + 1;
}
}
return ans;
}
};
复杂度分析
令 n 为数组长度。
35. 搜索插入位置
入选理由
暂无
题目地址
https://leetcode-cn.com/problems/search-insert-position
前置知识
暂无
题目描述
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。