自己也刷了一些算法题了,但是做起题来依旧很费劲,时常怀疑自己笨的过分。反思了一下,一是做完就扔,二是哪怕记了笔记,也因为没有条理性不太爱回顾,再者也没有按照分类刷题。所以停下来把之前做过的题整理一下,发到掘金上方便回顾复习。因为能力一般,刷的题大多还比较基础。 可能会分几个章节,第一篇先从
数组开始吧!
力扣35简单题:搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
二分查找:
二分可使时间复杂度降低到O(logN)
mid值与目标值相等直接返回下标。如果mid值小于目标数,则左指针右移;如果大于目标数,则右指针左移。
查找结束如果没有相等值则返回 left,该值为插入位置。
var searchInsert = function(nums, target) {
let left = 0, right = nums.length - 1;
while (left <= right) {
let mid = (left + right) >> 1;
if (nums[mid] === target) return mid;
if (nums[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return left;
};
力扣27简单题:移除元素
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
快慢指针:
快的在前面走,慢的在后面。如果快指针遇到了目标值,就再往前走,慢指针不动。 相当于慢的在遍历数组的时候重新赋值,返回这个慢的。
也就是说,未遇到目标值时,慢指针指向的位置正常赋值快指针指向的值,而遇到需要删除的值时,则快指针移动,慢指针不动。
var removeElement = function(nums, val) {
let slow=0;
for(let fast=0;fast<nums.length;fast++){
//正常情况直接赋值给
if(nums[fast]!==val){
nums[slow]=nums[fast];
slow++;
}
//如果为需要删除的值时,则快指针移动,慢指针不动。
}
return slow;
};
力扣26简单题:删除排序数组中的重复项
给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
和上题类似
var removeDuplicates = function(nums) {
if(nums.length==0) return 0;
let slow=0;
for(let fast=slow+1;fast<nums.length;fast++){
if(nums[fast]!=nums[slow]){
slow++;
nums[slow]=nums[fast];
}
}
return slow+1;
};
力扣209中等题:长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
双指针,滑动窗口思想:
定义两个指针,用来定位子数组的头和尾。 头指针往前走,然后不断的累加遍历的数,直到和sum大于给定的target,记录这个长度。 然后尾指针前移,看是否还是大于target,更新长度,直到sum小于target。 头指针再继续前移。 持续这个过程,直到头指针到达末尾。
var minSubArrayLen = function(target, nums) {
let sum=0;
let child =Infinity; //表示符合条件的子数组长度!
let j=0; //尾指针
for(let i=0;i<nums.length;i++){
sum+=nums[i];
while(sum>=target){
child=Math.min(i-j+1,child);
sum-=nums[j];
j++;
}
}
return child===Infinity?0:child;
};
未完待续,谁能想到做过的题再回顾还像新题一样,我好笨(ㄒoㄒ)