重新开始刷题了,第一天复习数组理论基础
考察数组的题目主要是考察对代码的掌握能力,数组是存放在连续内存空间上的相同类型数据的集合。
数组下标从0开始,内存地址连续,删除或增添已素时,需要移动其它素的地址
704. 二分查找
题目链接:https://leetcode.cn/problems/binary-search/description/
思路 1:遍历nums,如果当前下标的元素和 target相等则 return 当前坐标,并输出对应的下标其他情况下输出1这个时间复杂度是 O(n)空间复杂度是O(1)
var search = function(nums, target) {
for (let i = 0; i < nums.length; i = i + 1) {
if(nums[i] === target) {
return i
}
}
return -1
};
思路 2: 基于这是一个有序的数组,可以使用二分查找,首先定义出左边的变量和右边的变量,然后判断中位数和这个 target 的大小,不断缩小左边和右边数值的范围,然后最终确定和 target 相等的数值的索引;这个方法的时间复杂度为 O(logn), 空间复杂度为 O(1):实现代码如下:
var search = function(nums, target) {
let left = 0;
let right = nums.length
while(left <= right) {
let mid = Math.floor((left + right) / 2)
if(nums[mid] === target) {
return mid
} else if(nums[mid] < target) {
left = mid + 1
} else {
right = mid - 1 //已经判断了 num[mid]不是 target 的数值,左闭右闭区间必须不包含 mid
}
}
return -1
上述解法虽然通过了,但是其实混淆了左闭右闭,和左开右闭两种情况
卡哥解法
两种写法: 1.[left, right] 2.(left, right]
1.写法应为while(left <= right), 因为仍需考虑 left === right时,是否是目标元素
2. 写法为 while(left < right),当 num[mid] > target时, right更新为 middle(不变量本身就不包括 right,所以 right应该更新为 middle。
易混淆点: 1 区间问题,2. right的取值情况
27.移除元素
题目链接: . - 力扣(LeetCode)
思路: 暴力解法,遍历数组,如果发现当前位为 val,则将该位后面的元素集体往前移一位.
var removeElement = function(nums, val) {
let size = nums.length
for(let i = 0; i < size; i = i + 1) {
if(nums[i] === val) {
for(let j = i + 1; j < size; j = j + 1) {
nums[j - 1] = nums[j]
}
i = i - 1
size = size - 1
}
}
return size
};
双指针法的初步熟悉:
快指针: 寻找新数组的元素,寻找不等于目标元素的数
慢指针: 寻找更新新数组下标的位置
代码实现
var removeElement = function(nums, val) {
let slow = 0;
for(let quick = 0; quick < nums.length; quick = quick + 1) {
if(nums[quick] === val) continue
if(nums[quick] !== val) {
nums[slow++] = nums[quick]
}
}
return slow
};