算法训练第一天 | LeetCode 704. 二分查找 27. 移除元素 977.有序数组的平方

65 阅读3分钟

数组(part1)

704.二分查找

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 **/
var search = function (nums, target) {
    let left = 0;
    let right = nums.length - 1;
    let middle = 0;
    // 左闭右闭区间
    while (left <= right) {
        middle = parseInt((left + right) / 2);
        if (nums[middle] < target) {
            left = middle + 1;
        } else if (nums[middle] > target) {
            right = middle - 1;
        } else {
            return middle;
        }
    }
    return -1;
};
  • 独立做题思路:只想到了二分的算法实现,即在有序数组中通过对比中间值和目标值的大小,再通过大小改变区间范围,不断重复来寻找目标值。对于区间只是认为是一个范围,也没有具体的概念。对于其带来的问题只是根据未通过用例盲目的调整小于等于或者加一减一。
  • 学习后新思路:认识到算法本身和区间的定义息息相关。对于左闭右闭区间是可以取到区间两边的值的,所以while循环条件需要判断相等的情况。而对于左闭右开区间,区间右边的值取不到,所以while循环不会出现相等情况。对于中间值的问题,则需要根据区间定义判断边界值是否在上一次比较过,如果是左闭右闭则需要跳过左右边界值,相反左闭右开则不需要跳过右边界值而需要跳过左边界值。
  • 实现问题:发现本题会出现只有一个元素的数组,在选择左闭右开区间进行解题时无法覆盖该情况,需要特殊处理,而选择左闭右闭区间则可以覆盖。

27.移除元素

/**
 * @param {number[]} nums
 * @param {number} val
 * @return {number}
 **/
var removeElement = function (nums, val) {
    let k = 0; // k 为新数组元素的位置
    // i 为新数组的元素
    for (let i = 0; i < nums.length; i++) {
        // 当不等于val时,该元素即为新数组的元素
        if (nums[i] !== val) {
            nums[k++] = nums[i]; // 赋值后新数组的角标加一
        }
    }
    return k;
};
  • 独立做题思路:看到题目只想到遍历数组时用库函数把对应元素删了然后返回
  • 学习后新思路:了解了数组在内存中的存储方式,以及删除元素时库函数对数组的操作并不是删掉元素,而是覆盖元素并修改数组长度。按照这个思路联想到双指针实现元素覆盖,即一个指针确定新数组中需要的元素,一个指针确定新数组中元素的位置。
  • 实现问题:最开始不理解两个指针的含义,代码完全看不懂,理解之后一点即通。

977.有序数组的平方

/**
 * @param {number[]} nums
 * @return {number[]}
 **/
var sortedSquares = function (nums) {
    let len = nums.length;
    let arr = new Array(len).fill(0);
    let i = 0, j = len - 1;
    let k = j;
    while (i <= j) {
        let ii = nums[i] * nums[i];
        let jj = nums[j] * nums[j];
        if (ii > jj) {
            arr[k--] = ii;
            i++;
        } else {
            arr[k--] = jj;
            j--;
        }
    }
    return arr;
};
  • 独立做题思路:很直观的想法,数组平方后再排序或者先排序在计算平方
  • 学习后新思路:由于是计算平方,则最大值要么是最小的复数或者最大的正数,即两头的值是计算后最大的,所以用双指针从两头向中间遍历,当左指针的值比右指针的大,左指针向右移,反之亦然。
  • 实现问题:无,一切顺利