704.二分查找
力扣题目链接:https://leetcode.cn/problems/binary-search/
题目描述:
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。(所有元素不重复且数组为升序排列)
示例:
输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4
输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1
思路:
二分法查找的思路是不断地将数组二分,判断target应当属于哪个部分。思路很简单,但是应当注意边界条件的选取和每次二分的规则。
闭区间的查找规则:定义三个指针low,middle,high分别指向当前查找范围的第一、中间、最后的元素。在[low,right]中查找,那么也就意味着low和high对应元素的值也可能是target,我们在查找中就不能将low和high随意舍去。
代码如下:
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var search = function(nums, target) {
let len = nums.length
let low = 0
let high = len-1
let middle = Math.floor(high/2)
while(low <= high){
//target在低半部分
if(target >= nums[low] && target < nums[middle]){
//下面考虑了等于middle的值的情况,所以在这里要减1
high = middle - 1
middle = low + Math.floor((high - low) / 2)
}
//target在高半部分
else if(target <= nums[high] && target > nums[middle]){
low = middle + 1
middle = low + Math.floor((high - low) / 2)
}
//target在中间
else if(target === nums[middle]){
return middle;
}
//target不在数组最大和最小值之间的区间([nums[low],nums[high]])
else{
return -1;
}
}
//全部查找完但是没找到target
return -1;
};
还有一种左闭右开的方式,即查找的是[low,high),需要将high定义为数组最后一个元素的下标
+1,在更新时策略也有所不同,就不写了,理解了闭区间的思路这种方式也很好理解。
27.移除元素
力扣题目链接:https://leetcode.cn/problems/remove-element/
题目描述:
给你一个数组 nums
和一个值 val
,你需要原地移除所有数值等于 val
的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1)
额外空间并原地修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
示例:
输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。
输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,4,0,3]
解释:函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。
思路:
看到这个题目的第一眼就想到了选择排序、插入排序的那种做法:使前k个元素有序,不断地将后面的元素放到前面这k个元素中。
需要两个指针low,high。low从前往后,high从后往前。在一次循环中,递增low直至找到不符合的元素,递减high直至找到符合条件的元素,将二者互换,使low之前全为符合条件的,high之后全为不符合条件的。本题可以不用互换,因为不用考虑超出新长度后面的元素。
代码如下:
/**
* @param {number[]} nums
* @param {number} val
* @return {number}
*/
var removeElement = function(nums, val) {
let len = nums.length
if (len === 0) return 0
let low = 0
let high = len-1
while(1){
while(nums[low] !== val){
if(low === len) return len //全都不用删除
low++
}
while(nums[high] === val){
if(high === 0) return 0 //全要删除
high--
}
if(low > high) break
//交换,或者直接覆盖也行:nums[low] = nums[high]
let tmp = nums[low]
nums[low] = nums[high]
nums[high] = tmp
}
return low
};
标签:元素,target,nums,javascript,随想录,day1,high,middle,low
From: https://www.cnblogs.com/endmax/p/16894720.html