一、刷题顺序
跟着大佬:https://github.com/CyC2018/CS-Notes leetcode题解
的顺序在慢慢刷,本篇文章讲到的是双指针。
二、双指针
图解来自我觉得讲得比较好的视频:https://www.youtube.com/watch?v=2wVjt3yhGwg
双指针分为以下两种思路,我们也需要在不同的题型中分别应用这两种思路:
先放一个简单的例子讲解Opposite directional two pointer algorithm:
其后是Equi-directional:
三、具体题目
以下这些题目用双指针来做都是最优解:
167. 两数之和Ⅱ
var twoSum = function(numbers, target) {
for(let i = 0, j = numbers.length - 1; i < j;){
let sum = numbers[i] + numbers[j];
if(sum < target){
i++;
}
else if(sum > target){
j--;
}
else{
return [i+1,j+1]
}
};
return null
};
633. 两数平方和
if(c < 0) return false;
for(let i = 0,j = Math.floor(Math.sqrt(c));i <= j;){
let sum = i*i + j*j;
if(sum < c){
i++;
}
else if(sum > c){
j--;
}
else{
return true
}
}
return false
345. 反转字符串中的元音字符
var vowels = new Set(['a','e','i','o','u','A','E','I','O','U']);
var newS = s.split('');
var len = newS.length;
var left = 0, right = len -1;
while(left<right){
if(vowels.has(newS[left])){
if(vowels.has(newS[right])){
[newS[left],newS[right]]=[newS[right],newS[left]];
left++;
}
right--;
}else{
left++;
}
}
return newS.join('')
在该题的代码中,值得注意的是:
-
元音应包含大小写。
-
需要先将字符串分割为字符串数组。
原因:字符串是受限的序列与典型的序列类型。它不具备列表的如下操作:append()、clear()、copy()、insert()、pop()、remove(),等等。其中,append()、insert()、pop() 和 remove(),这些方法都是对单个元素的操作,但是,字符串中的单个元素就是单个字符,通常没有任何意义,我们也不会频繁对其做增删操作,所以,字符串没有这几个方法。
split()
方法返回结果如下:
"hello".split("") //可返回 ["h", "e", "l", "l", "o"]
-
使用到了
set.has()
函数接受一个值并验证当前对象是否包含指定值。 -
[a,b]=[b,a]
为ES6中的解构语法,且改变原数组,所以只需要使用join('')
将数组中的各个元素重新连接为字符串return
即可。 -
什么时候用for循环,什么时候用while循环?
知道具体循环次数时,使用for循环;不知道具体循环次数,只知道结束条件时,使用while循环。两者的功能是相似的。