双指针分: 左右双指针 快慢指针 滑动窗口三种
leetcode 26题 删除有序数组中的重复项(原地删除)
解法1 从大到小遍历,和前一个数比较, 相同的话删除后面的. 如果是从小到大遍历的话,会少删. […new Set(arr)]
var removeDuplicates = function(nums) {
let len = nums.length
for(let i = len - 1; i > 0; i--){
if(nums[i] === nums[i - 1]){
nums.splice(i, 1)
}
}
return nums.length
};
解法2 快慢指针
var removeDuplicates = function(nums) {
let slow = 0;
let quick = 0;
while(quick < nums.length){
if(nums[slow] !== nums[quick]){
slow++
nums[slow] = nums[quick]
}
quick++
}
return slow+1
};
leetcode 83. 删除排序链表中的重复元素
var deleteDuplicates = function(head) {
if(head === null) return null
let s = head;
let q = head;
while(q !== null) {
if(q.val !== s.val) {
s.next = q
s = s.next
}
q = q.next
}
s.next = null
return head
};
27. 移除元素
也可以按26题的解法一.
344. 反转字符串
这道题过于简单了可以直接用数组的 reverse()方法了. 连 spilt('').reverse().join('') 都不用.
// [a, b] = [b, a] 解构赋值交换值
var reverseString = function (s) {
let l = 0;
let r = s.length - 1;
while(l < r) {
[s[l], s[r]] = [s[r], s[l]]
l++
r--
}
return s
};
leetcode 5. 最长回文子串
/**
* @param {string} s
* @return {string}
*/
var longestPalindrome = function(s) {
let max = ''
for(let i=0; i< s.length; i++) {
// 分奇偶, 一次遍历,每个字符位置都可能存在奇数或偶数回文
helper(i, i) // 以 i为中心的, 奇数回文字
helper(i, i+1) // 偶数回文字
}
function helper(l, r) {
// 定义左右双指针
while(l>=0 && r< s.length && s[l] === s[r]) {
l-- // 扩大范围
r++
}
// 拿到回文字符, 注意 上面while满足条件后多执行了一次,所以需要缩小. l + 1 r - 1, slice 含头不含尾, 所以要 + 1
const maxStr = s.slice(l + 1, r - 1 + 1);
// 取最大长度的回文字符
if (maxStr.length > max.length) max = maxStr
}
return max
};
// 判断一个字符串是不是回文字.
var isPalindrome = function(s) {
// 一左一右两个指针相向而行
let left = 0, right = s.length-1;
while (left < right) {
if (s.charAt(left) !== s.charAt(right)) {
return false;
}
left++;
right--;
}
return true;
};
滑动窗口老猛男, 子串问题全靠它
int left = 0, right = 0;
while (left < right && right < s.length) {
// 增大窗口
window.add(s[right]);
right++;
while (window needs shrink) {
// 缩小窗口
window.remove(s[left]);
left++;
}
}