704 二分查找
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
重点是边界问题,有左闭右闭,左闭右开两种情况
左闭右闭:left可以等于right,while(left<=right),而if判断时由于right可以取到,middle已经被排除,所以更新right为middle+1
左闭右开:left不可以等于right(此时等于无意义,例如[1,1)),while(left<ight),而if判断时由于right可以不取到,所以更新right为middle
左闭右闭:
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var search = function(nums, target) {
let left = 0,right = nums.length-1;
let mid = 0
while(left <= right){
mid = left + ((right - left) >> 1)
if(nums[mid] < target){
left = mid + 1
}else if(nums[mid] > target){
right = mid - 1
}else {
return mid;
}
}
return -1
};
左闭右开
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var search = function(nums, target) {
let left = 0,right=nums.length;
let mid = 0
while(left < right){
mid = left + ((right - left) >> 1)
if(nums[mid] < target){
left = mid + 1
}else if(nums[mid] > target){
right = mid
}
else{
return mid
}
}
return -1
};
35 搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
这个返回left具体流程没有想明白,是通过图解画出来的
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var searchInsert = function(nums, target) {
let left=0,right=nums.length-1;
let mid = 0;
while(left <= right){
mid = left + ((right - left) >> 1)
if(nums[mid] > target){
right = mid -1
}else if(nums[mid] < target){
left = mid + 1
}else{
return mid
}
}
return left
};
34 在排序数组中查找元素的第一个和最后一个位置
给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]
第一种
这个不是算法,使用的js数组方法,也记录下来吧
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var searchRange = function(nums, target) {
let start = nums.indexOf(target)
let end = nums.lastIndexOf(target)
return [start,end]
};
第二种
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var searchRange = function(nums, target) {
//if(nums.length===0) return [-1,-1]
let start = 0,end = nums.length -1
let mid = 0;
while(start <= end){
mid = start + ((end - start) >> 1)
if(nums[mid] < target){
start = mid + 1
}else if(nums[mid] > target){
end = mid - 1
}else if(nums[mid] == target){
start = mid;
end = mid
while(nums[start] === target){
start--
}
while(nums[end] === target){
end++
}
return [start+1,end-1]
}
}
return [-1,-1]
};
第三种
/**
* @param {number[]} nums
* @param {number} target
* @return {number[]}
*/
var searchRange = function(nums, target) {
//if(nums.length===0) return [-1,-1]
let start = 0,end = nums.length -1
let firstPos = -1,lastPos = -1
while(start <= end){
let mid = start + ((end - start) >> 1)
if(nums[mid] < target){
start = mid + 1
}else if(nums[mid] > target){
end = mid -1
}else{
firstPos = mid
end = mid -1
}
}
if(firstPos === -1) return [-1,-1]
start = 0,end = nums.length -1
while(start <= end){
let mid = start + ((end - start) >> 1)
if(nums[mid] < target){
start = mid + 1
}else if(nums[mid] > target){
end = mid -1
}else{
lastPos = mid
start = mid +1
}
}
return [firstPos,lastPos]
};
27 移除元素
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。
假设 nums 中不等于 val 的元素数量为 k,要通过此题,您需要执行以下操作:
更改 nums 数组,使 nums 的前 k 个元素包含不等于 val 的元素。nums 的其余元素和 nums 的大小并不重要。
返回 k
解题思路是利用双指针,定义一个快指针fast用来寻找新数组需要的元素,定义一个慢指针low来填充新数组,利用 if 判断 if(nums[fast]!=val) 将新数组需要的元素找到,不需要的元素跳过,继续进行 for 循环
暴力解法,就是两个for循环
/**
* @param {number[]} nums
* @param {number} val
* @return {number}
*/
var removeElement = function(nums, val) {
let len = nums.length;
for(let i = 0; i < len;i++){
if(nums[i] === val){
for(let j = i+1;j < len;j++){
nums[j-1] = nums[j]
}
i--;
len--
}
}
return len
};
双指针,也就是滑动窗口
/**
* @param {number[]} nums
* @param {number} val
* @return {number}
*/
var removeElement = function(nums, val) {
let fast=0,slow=0;
for(fast=0;fast<nums.length;fast++){
if(nums[fast] !== val){
nums[slow] = nums[fast]
slow++
}
}
return slow
};
977 有序数组的平方
给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
这个思路是如果数组里面全部是正数,那么平方之后的数组肯定也是 非递减序列,所以如果数组中存在负数,平方之后,大数在两边,小数在中间
也是利用双指针的写法,从开头和结尾分别开始,哪个数比较大,就先推那个数进入数组
/**
* @param {number[]} nums
* @return {number[]}
*/
var sortedSquares = function(nums) {
nums = nums.map(item => item * item)
let left=0,right=nums.length-1;
let array = []
while(left<=right){
if(nums[left] > nums[right]){
array.push(nums[left])
left++
}else{
array.push(nums[right])
right--
}
}
return array.reverse()
};
/**
* @param {number[]} nums
* @return {number[]}
*/
var sortedSquares = function(nums) {
nums.forEach((num,index)=>{
nums[index] = num*num
})
let len = nums.length
let array = new Array(len).fill(0)
let start=0,end = nums.length-1
while(start <= end){
if(nums[start] > nums[end]){
array[len-1] = nums[start]
start++
}else{
array[len-1] = nums[end]
end--
}
len--
}
return array
};