26. 删除排序数组中的重复项

可以设立双指针(一快一慢)。快指针不断++。当快指针和慢指针的元素不相等时,将快指针指向的元素赋值给慢指针的下一个元素:

  1. /**
  2. * @param {number[]} nums
  3. * @return {number}
  4. */
  5. var removeDuplicates = function(nums) {
  6. let j = 0;
  7. for(let i = 1; i < nums.length; i++) {
  8. if(nums[i] !== nums[j]) {
  9. nums[j+1] = nums[i]
  10. j++
  11. }
  12. }
  13. return j + 1
  14. };

189. 旋转数组

2种解法:

  • 在数组最后截取出来k个元素,然后 unshift 到数组头部
  • 遍历k次,每次弹出数组最后一个放在最前面
    1. /**
    2. * @param {number[]} nums
    3. * @param {number} k
    4. * @return {void} Do not return anything, modify nums in-place instead.
    5. */
    6. var rotate = function(nums, k) {
    7. for(let i = 0; i < k; i++) {
    8. nums.unshift(nums.pop())
    9. }
    10. return nums
    11. };

21. 合并两个有序链表

该题可以使用递归法:

  1. /**
  2. * Definition for singly-linked list.
  3. * function ListNode(val, next) {
  4. * this.val = (val===undefined ? 0 : val)
  5. * this.next = (next===undefined ? null : next)
  6. * }
  7. */
  8. /**
  9. * @param {ListNode} l1
  10. * @param {ListNode} l2
  11. * @return {ListNode}
  12. */
  13. var mergeTwoLists = function(l1, l2) {
  14. if(l1 === null) {
  15. return l2;
  16. }
  17. if(l2 === null) {
  18. return l1;
  19. }
  20. if(l1.val < l2.val) {
  21. l1.next = mergeTwoLists(l1.next, l2)
  22. return l1;
  23. } else {
  24. l2.next = mergeTwoLists(l1, l2.next)
  25. return l2
  26. }
  27. };

88. 合并两个有序数组

测试用例:

  1. [3, 5, 0, 0, 0]
  2. 2
  3. [1, 2, 6]
  4. 3

设立三个指针:p1,p2,p。分别指向 nums1数组自身实际存在最后一个值的下标,nums2数组自身实际存在最后一个值的下标,两个数组合并后的总长度最后一个值下标。

按照从后向前进行遍历。如果p2的值大于p1的值,那么放在nums1的最后面 (替换0);如果小于或者等于,则将p1自身的值复制到p指针的位置。跑完一遍while后:

  1. 3, 5, 3, 5, 6

因为p2是慢指针,只有值存到了p1内才会继续移动。所以此时p2指针指向了nums2的1号下标。

此时需要手动矫正,将nums1内从0开始,删除下标为1及其之前的元素;然后将nums2内剩余没复制过去的元素,复制过去(index为1)

  1. /**
  2. * @param {number[]} nums1
  3. * @param {number} m
  4. * @param {number[]} nums2
  5. * @param {number} n
  6. * @return {void} Do not return anything, modify nums1 in-place instead.
  7. */
  8. var merge = function(nums1, m, nums2, n) {
  9. let p1 = m - 1;
  10. let p2 = n - 1;
  11. let p = m + n - 1;
  12. while(p1 > -1 && p2 > -1) {
  13. nums1[p--] = nums1[p1] > nums2[p2] ? nums1[p1--] : nums2[p2--]
  14. }
  15. nums1.splice(0, p2 + 1)
  16. nums1.unshift(...nums2.splice(0, p2 + 1))
  17. };

1. 两数之和

本题借助Map表的思维,将target和当前值的差值存放为key(数组index)。向后遍历过程中,如果当前遍历到的值在Map表内,则代表有相对差值,匹配成功。

  1. /**
  2. * @param {number[]} nums
  3. * @param {number} target
  4. * @return {number[]}
  5. */
  6. var twoSum = function(nums, target) {
  7. let map = [];
  8. for (let i = 0; i < nums.length; i++) {
  9. let dis = target - nums[i];
  10. if (map[nums[i]] === undefined) {
  11. map[dis] = i
  12. } else {
  13. return [map[nums[i]], i]
  14. }
  15. }
  16. };

283. 移动零

设立快慢指针,慢指针指向0的位置,快指针不断向后指。如果找到不是0的元素,则和慢指针交换元素。如果这两个指针没重叠,则将快指针的位置设置为0

  1. /**
  2. * @param {number[]} nums
  3. * @return {void} Do not return anything, modify nums in-place instead.
  4. */
  5. var moveZeroes = function(nums) {
  6. let j = 0;
  7. let i = 0;
  8. while(i < nums.length) {
  9. if (nums[i] !== 0) {
  10. nums[j] = nums[i]
  11. if (i !== j) {
  12. nums[i] = 0
  13. }
  14. j++
  15. }
  16. i++
  17. }
  18. return nums
  19. };

66. 加一

将数字数组从后向前遍历。数字挨个+1。

  • 如果加1后的数字➗10取余数为0,则代表要进位,继续向前遍历+1。
  • 如果取余数不为0,则代表不需要进位。直接返回数组即可
  • 如果碰上999,9999,999999这种数字,倒序循环后并不会生成最高位的1,则需要手动补1
    1. /**
    2. * @param {number[]} digits
    3. * @return {number[]}
    4. */
    5. var plusOne = function(digits) {
    6. for (let i = digits.length - 1; i > -1; i--) {
    7. digits[i]++
    8. digits[i] = digits[i] % 10;
    9. if(digits[i] !== 0) {
    10. return digits
    11. }
    12. }
    13. return [1, ...digits]
    14. };