双指针
第 167 题
有序数组的 Two Sumopen in new window
var twoSum = function (numbers, target) {
// 定义数组头尾双指针
let i = 0
let j = numbers.length - 1
// 判断当前值与双指针值和的大小
while (numbers[i] + numbers[j] !== target) {
if (numbers[i] + numbers[j] > target) {
// 超过右指针左移
j--
}
if (numbers[i] + numbers[j] < target) {
// 不足左指针右移
i++
}
}
// 返回符合结果值的位置
return [i + 1, j + 1]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
第 633 题
var judgeSquareSum = function (c) {
// 定义双指针,右指针为目标数平方根取整
let i = 0
let j = parseInt(Math.sqrt(c))
// 返回值
let result = false
// 左指针小于右指针的时候循环
// <= 处理特殊用例 2
while (i <= j) {
// 发现符合条件跳出循环
if (i * i + j * j === c) {
result = true
break
}
// 超过右指针左移
if (i * i + j * j > c) {
j--
}
// 不足左指针右移
if (i * i + j * j < c) {
i++
}
}
return result
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
第 345 题
var reverseVowels = function (s) {
// 定义双指针
let i = 0
let j = s.length - 1
// 字符串转数组,定义元音字母Set类型
let arr = s.split('')
let res = new Set(['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'])
while (i < j) {
// 利用Set类型has判断是否两个指针都为元音字符
// 都为元音字符时交换两个元音字符,并移动指针
if (res.has(arr[i]) && res.has(arr[j])) {
let mid = arr[i]
arr[i] = arr[j]
arr[j] = mid
i++
j--
}
// 左指针不为元音字符,右移
if (!res.has(arr[i])) {
i++
}
// 右指针不为元音字符,左移
if (!res.has(arr[j])) {
j--
}
}
// 返回合并值
return arr.join('')
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
第 88 题
var merge = function (nums1, m, nums2, n) {
// 定义双指针为两个数组的末尾,则总共需要处理的位数为p
let i = m - 1
let j = n - 1
let p = i + j + 1
while (p >= 0) {
// 当两个数组都还有元素未处理时,判断元素大小
if (i >= 0 && j >= 0) {
// 将较大的数放在p位置,并移动相应指针,p位置左移。
if (nums1[i] < nums2[j]) {
nums1[p--] = nums2[j--]
} else {
nums1[p--] = nums1[i--]
}
}
// 左指针已经没有元素时,直接将右指针元素放在p位置
if (i < 0 && j >= 0) {
nums1[p--] = nums2[j--]
}
// 右指针已经没有元素时,直接将左指针元素放在p位置
if (i >= 0 && j < 0) {
nums1[p--] = nums1[i--]
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
第 141 题
var hasCycle = function (head) {
// 处理链表为空或只有一个节点的情况
if (!head || !head.next) {
return false
}
// 定义快慢指针
let l1 = head
let l2 = head.next
// 快慢指针所指向的节点都存在时进行循环
while (l1 && l2 && l2.next) {
if (l1 === l2) {
return true
}
// 快指针每次前进两个节点,如果存在环,快指针必然将绕圈之后追上慢指针
l1 = l1.next
l2 = l2.next.next
}
return false
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
第 524 题
通过删除字母匹配到字典里最长单词open in new window
var findLongestWord = function (s, d) {
// 将传入的数组按字典序排序
let arr = d.sort()
// 分割传入的字符串为数组
let sArr = s.split('')
// 定义返回值
let str = ''
// 对匹配数组的每一项都进行遍历
for (let i = 0; i < arr.length; i++) {
// 将当前项拆分为数组,定义当前满足条件子字符串的长度k
let item = arr[i].split('')
let k = 0
// 对字符逐个匹配,匹配成功时k指针右移
for (let p = 0; p < sArr.length; p++) {
if (sArr[p] === item[k]) {
k++
}
}
// k值等于当前单词的长度时表示当前单词匹配成功
// 在大于之前匹配成功的单词长度时更新单词
if (k === item.length && k > str.length) {
str = arr[i]
}
}
return str
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26