DAY1 md还是喜欢用obsidian写好
704. 二分查找
题目 :
给定一个 n
个元素有序的(升序)整型数组 nums
和一个目标值 target
,写一个函数搜索 nums
中的 target
,如果目标值存在返回下标,否则返回 -1
。
示例 1:
输入: nums = [-1,0,3,5,9,12]
, target
= 9
输出: 4
示例 2:
输入: nums = [-1,0,3,5,9,12]
, target = 2
输出: -1
提示:
- 你可以假设
nums
中的所有元素是不重复的。 n
将在[1, 10000]
之间。nums
的每个元素都将在[-9999, 9999]
之间。
思路:
二分法的思想,首先要设定边界值,看数组是左闭右闭还是左闭右开,确定好边界条件,left
和right
,并根据left,right
计算中间值,在 JS 中需要采用Math.floor
(向下取整) 进行中位数字middle
的计算。
左闭右闭、左闭右开
while
循环的条件需要考虑到left
和right
是否可以相等
接着进行范围的判断,如果nums[middle] < target
,意味着中位数字middle
在target
的左边,需要将右边界值进行更新,更新为middle - 1
,为什么是-1
呢,因为nums[middle]
是已经在判断nums[middle] < target
确认是小于target
而不是等于,所以不需要再一次考虑,只需要比middle
更小的部分即可。nums[middle] > target
同理。
左闭右闭
const search = function (nums, target) {
let left = 0
let right = nums.length - 1
while (left <= right) {
let middle = Math.floor((left + right) / 2)
if (nums[middle] > target) {
right = middle - 1
} else if (nums[middle] < target) {
left = middle + 1
} else if (nums[middle] === target) {
return middle
}
}
return -1
};
左闭右开
const search = function (nums, target) {
let left = 0
let right = nums.length
while (left < right) {
let middle = Math.floor((left + right) / 2)
if (nums[middle] > target) {
right = middle
} else if (nums[middle] < target) {
left = middle + 1
} else if (nums[middle] === target) {
return middle
}
}
return -1
};
27. 移除元素
题目:
给你一个数组 nums
和一个值 val
,你需要 原地 移除所有数值等于 val
的元素。元素的顺序可能发生改变。然后返回 nums
中与 val
不同的元素的数量。
假设 nums
中不等于 val
的元素数量为 k
,要通过此题,您需要执行以下操作:
- 更改
nums
数组,使nums
的前k
个元素包含不等于val
的元素。nums
的其余元素和nums
的大小并不重要。 - 返回
k
。
示例 1:
输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2,_,_]
示例 2:
输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,4,0,3,_,_,_]
思路: 数组是难以增加或者删除元素,所以如果要删除,需要通过将后一位的数字覆盖前一位的数字,这时候,需要定义两个指针,一个是快指针,一个是慢指针,快指针是用来查找需要删除的数字,满指针是用来记录需要删除数字的索引,并用不需要删除书的值替换。
var removeElement = function (nums, val) {
let slowIndex = 0
for (let fastIndex = 0; fastIndex < nums.length ; fastIndex++) {
if(nums[fastIndex] !== val){
nums[slowIndex] = nums[fastIndex]
slowIndex++
}
}
return slowIndex;
};
977. 有序数组的平方
题目 :
给你一个按 非递减顺序 排序的整数数组 nums
,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例 1:
输入: nums = [-4,-1,0,3,10]
输出: [0,1,9,16,100]
示例 2:
输入: nums = [-7,-3,2,3,11]
输出: [4,9,9,49,121]
思路:
直接用 JS 数组的函数实现
var sortedSquares = function(nums) {
return nums.map(item => item * item).sort((x,y)=>(x-y))
};//map 让每个元素都实现后面的方法,sort 排序
通过双指针发实现,设定两个指针,分别在数组索引的 0 位和数组的 length - 1 位,并创建一个新的数组,对原始数组 0 位和末位元素的平方进行比较,若末位元素平方较大,则存到新数组的最后一位,并且指针向前移动,若 0 位元素平法较大,同样存到新数组的最后一位,指针向后移动。
var sortedSquares = function (nums) {
let result = []
let k = nums.length - 1
for (let i = 0, j = nums.length - 1; i <= j;) {
if (Math.pow(nums[i], 2) < Math.pow(nums[j], 2)) {
result[k] = Math.pow(nums[j], 2)
k--
j--
} else {
result[k] = Math.pow(nums[i], 2)
k--
i++
}
}
return result
};
283. 移动零
题目:
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
示例 2:
输入: nums = [0]
输出: [0]
思路:
- 通过快慢指针,对非 0 元素和 0 元素进行交换,使得所有的非 0 元素都到数组前面,0 都在数字后面。拿
[1,0,2,0,3]
为例子,第一次快慢指针都指向 1,这个时候都没有指向 0,所以将快指针的数值赋值给慢指针对应数组索引位置,并且快慢指针同时向前,第二次快慢指针都指向了 0,这个时候需要进行记录,慢指针记录当前 0 所在索引位置,快指针继续向前寻找,第三次快指针指向了 2,慢指针没有变化,还是对应 0 的索引位置 1,此时需要将两个元素进行调换,这个时候数组变为[1,2,0,0,3]
,并且需要让快慢指针都向前移动,此时慢指针依旧指向了之前的 0,但是索引位置已经发生变化,此时快指针指向了第二个 0,根据判断,为 0 则快指针继续向前,第五次快指针指向了 3,慢指针对应的是 0 的索引位置 2,此时需要将两个元素进行调换,这个时候数组就变成了[1,2,3,0,0]
完成将 0 移动到数组末尾。
var moveZeroes = function(nums) {
let slowIndex = 0
for(let fastIndex = 0;fastIndex < nums.length ; fastIndex++){
if(nums[fastIndex] !== 0){
[nums[slowIndex],nums[fastIndex]] = [nums[fastIndex],nums[slowIndex]]
slowIndex++
}
}
};
- 通过快慢指针,通过将后面元素覆盖掉 0 所在的元素,返回新数组长度,并根据该长度将以此长度为初始索引到数组长度索引的数组元素全部替换成 0;
var moveZeroes = function(nums) {
let slowIndex = 0
for(let fastIndex = 0;fastIndex < nums.length ; fastIndex++){
if(nums[fastIndex] !== 0){
nums[slowIndex] = nums[fastIndex]
slowIndex++
}
}
nums.fill(0,slowIndex,nums.length)
};