结合最近刷的一些题目,会陆续总结出相类似的题目和大家一起解体,持续更新中.
下面我们先来几道开胃菜:
26. 删除有序数组中的重复项
/**
* @param {number[]} nums
* @return {number}
*/
var removeDuplicates = function(nums) {
let fast = 0, slow = 0;
while(fast < nums.length) {
if (nums[slow] === nums[fast]) {
fast++;
} else if (nums[slow] !== nums[fast]) {
slow++;
// 维护 nums[0..slow] 无重复
nums[slow] = nums[fast];
}
}
// 长度等于 数组长度 + 1;
return slow + 1;
};
83. 删除排序链表中的重复的元素
这道题和上题不同地方在于,我们需要用链表的思路去逐个遍历, 将重复的元素删除
删除的思路就是 当 slow.next = fast, 更新 slow = slow.next.这里在处理的时候,会需要在最后while 结束之后,注意断开slow与后面连接slow.next = null。
var deleteDuplicates = function(head) {
if (head === null) return null;
let slow = head, fast = head;
while(fast) {
if (fast.val !== slow.val) {
// 删除元素
slow.next = fast;
slow = slow.next;
}
// 继续更新 fast
fast = fast.next;
}
slow.next = null;
return head;
}
27. 移除元素
从题目中可以看出, 其实已经给出了重复的值是谁,那么我们需要做的事情,就变成了根据val
的值去找到对应的元素,进行对应的删除操作.
var removeElement = function(nums, val) {
let slow = 0, fast = 0, n = nums.length;
while(right < n) {
// nums[fast] === val 需要做什么?
if (nums[fast] !== val) {
nums[slow] = nums[fast];
slow++;
}
fast++;
}
return slow;
}
283. 移动零
其实这道题目,如果你对上面的几道题细细评味的话,你就会觉得这道题其实确实很简单.
简单在哪里呢? 首先是我们看题意把所有0移动到数组的末尾,我们可以转换为另一种思维是不是要我去把 0 当作重复的元素的从原数组中拿出来,将剩下的元素按照之前的顺序存储,那么我们结合 上题的返回值和 原数组的长度将 数组重新拼接起来.
那我就说到这里了,你是不是已经摩拳擦掌了,迫切的想去试试了呢?
var moveZeroes = function(nums) {
let n = nums.length;
let p = removeZero(nums, 0);
// 组合新的数组
for (; p < n; p++) {
nums[p] = 0;
}
return nums;
}
function removeZero(nums, val) {
let fast = 0, slow = 0;
while(fast < nums.length) {
if (nums[fast] !== val) {
nums[slow] = nums[fast]
slow++;
}
fast++;
}
return slow;
}
下面我们要开始上难度了
42. 接雨水
对于接雨水系列我会出一个比较详细的教程,去慢慢解读它的思路,# 雨水☔️ 该怎么样才好接呢?;现在呢,我先放出最终的解法
在写之前,我们可以简单的梳理一下, 我们需要关注的点是 每次i能装多少水 然后计算每次能装最多的水,但是 每次能装的水其实会和两个变量有关系, 我们暂时定为 l_max[i],
r_max[i];
仔细慢慢想想 他们之间是不是有什么关系呢?
water[i] = Math.min(l_max, r_max) - height[i]
l_max = Math.max(l_max, height[left])
r_max = Math.max(r_max, height[right])
到这里大家是不是开始有点感觉了呢?让我们一起试试吧。
// 双指针
// 用双指针 边走边算 节省出那部分空间来
var trap = function(height) {
let left = 0, right = height.length-1;
let l_max = [], r_max = [], res = 0;
while (left < right) {
// 是不是很熟悉的操作
l_max = Math.max(l_max, height[left]);
r_max = Math.max(r_max, height[right]);
// 这里是决定谁去更新
if (l_max < r_max) {
res += l_max - height[left];
// 更新
left++;
} else {
res += r_max - height[right];
right++:
}
}
return res;
}
到这里, 你是不是和我一样收获满满呢, 希望我们都可以坚持下去✊。
题目链接🔗: