数组题-双指针技巧

数组没有真正意义上的指针,可以把索引当作指针。

快慢指针:

leetcode:26. 删除有序数组中的重复项

解题思路: 快慢指针

让快指针先走,找到一个不重复的元素就赋值给慢指针,并让慢指针前进,快指针遍历完,nums[0..slow]得到的就是整个数组去重的结果

var removeDuplicates = function(nums) {
  if (nums.length == 0) return 0
  let slow = 0, fast = 0
  while (fast < nums.length) {
    if (nums[fast] != nums[slow]) {
      slow++ 
      nums[slow] = nums[fast] 
    }
    fast++
  }
  return slow+1 //数组长度为索引+1
};

leetcode:83. 删除排序链表中的重复元素 

解题思路: 快慢指针技巧

同上面数组解答,唯一的区别就是把数组的赋值换成操作指针 

var deleteDuplicates = function(head) {
  if (!head) return null
  let slow = head, fast = head
  while (fast) {
    if (fast.val != slow.val) {
      slow.next = fast
      slow = slow.next
    }
    fast =fast.next
  }
  slow.next = null //断开与后面重复元素的链接
  return head
};

 leetcode:27. 移除元素

解题思路: 快慢指针技巧

让快指针先走,遇到为val的元素,直接跳过,否则就赋值给慢指针,并让慢指针前进。

和第一题的区别是先赋值再指针++,这样可以保证是不包含val的,slow就是结果数组的长度。

var removeElement = function (nums, val) {
  let fast = slow = 0
  while (fast < nums.length) {
    if (nums[fast] != val) {
      nums[slow] = nums[fast]
      slow++
    }
    fast++
  }
  return slow

};

 leetcode:283. 移动零

解题思路: 快慢指针

移除nums中所有的0,再把后面元素都赋值为0 

//采用上一题的移除元素
var removeElement = function (nums, val) {
  let fast = slow = 0
  while (fast < nums.length) {
    if (nums[fast] != val) {
      nums[slow] = nums[fast]
      slow++
    }
    fast++
  }
  return slow

};
var moveZeroes = function (nums) {
  let p = removeElement(nums,0) //返回不含0的数组长度
  for (; p < nums.length; p++) { //剩下的赋值0
    nums[p] = 0
    
  }
};

左右指针

 leetcode:167. 两数之和 II - 输入有序数组

解题思路:类似二分查找 

var twoSum = function(numbers, target) {
  let left = 0, right = numbers.length - 1
  while (left < right) {
    let sum = numbers[left] + numbers[right]
    if (sum == target) {
      return [left+1,right+1] //题目要求+1
    } else if (sum < target) {
      left++
    } else {
      right--
    }
  }
};

 leetcode:344. 反转字符串

解题思路:一左一右两个指针相向而行,相互交换 

var reverseString = function(s) {
  let left = 0, right = s.length - 1
  while (left < right) {
    let tmp = s[left]
    s[left] = s[right]
    s[right] = tmp
    left++
    right--
  }
};

leetcode:5. 最长回文子串 

 解题思路:

让左右指针从中心向两侧扩展

//寻找以left,right为中心的最长回文串
var palindrome = function (s,left,right) {
  while (left >= 0 && right < s.length && s.charAt(left) === s.charAt(right)) {
    left--
    right++
  }
  return s.substring(left+1,right)
}
var longestPalindrome = function(s) {
  let res = ''
  for (let i = 0; i < s.length; i++) {
    let s1 = palindrome(s, i, i) //如果left和right相同==寻找长度为奇数的回文串
    let s2 = palindrome(s, i, i + 1) //如果left和right相邻==寻找长度为偶数的回文串
    res = res.length > s1.length ? res : s1
    res = res.length > s2.length ? res : s2   
  }
  return res
};

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值