双指针(力扣hot)

98 阅读2分钟

力扣对应的双指针共4题

力扣283.移动零

解题思路:定义两个指针,左指针标记数组上一个塞入0的位置,右指针用于遍历数组,当右指针的值不等于0,左指针和右指针替换位置,左指针+1记录下一个0的位置

/**
 * @param {number[]} nums
 * @return {number}
 */

const moveZeroes=(nums)=>{
    let left = 0;
    for(let right = 0;right<nums.length;right++){
        if(nums[right] !== 0){
            [nums[left],nums[right]] = [[nums.right],[nums.left]];
            left++
        }
    }
}

力扣11.盛最多水的容器

解题思路:面积的求和是两个高度直接的距离*两高度的低值,先计算首尾,向内移动短板可能会变大,但是向内移动长板会不变或变小,所以采用向内移动短板的方式

/**
 * @param {number[]} heights
 * @return {number}
 */

const maxArea=(heights)=>{
    let left = 0;
    let right = heights.length - 1;
    let maxArea = 0;
    while(left<right){
        const currentArea = Math.min(heights[left],heights[right])*(right-left);
        maxArea = Math.max(maxArea,currentArea);
        if(heights[left]<heights[right]){
            left++
        }else{
            right--
        }
    }
    return maxArea
}

力扣15.三数之和

解题思路:取三数之和等于0,首先要进行排序。排序之后遍历数组,获取某一项时,采用双指针记录另外两项的值,因为是排过序,双指针去此项之后的收尾两项,根据结果大小,移动不同指针,搜索出结果存不存在。

/**
 * @param {number[]} nums
 * @return {number[][]}
 */

const threeSum=(nums)=>{
    let arr = [];
    let len = nums.length;
    if(nums == null || len<3) return arr;
    nums.sort((a,b)=>a-b)
    for(let i = 0;i<len;i++){
        if(nums[i]>0) break;
        if(i>0 && nums[i] == nums[i-1]) continue
        let left = i+1;
        let right = len - 1;
        while(left<right){
            let sum = nums[i] + nums[right] + nums[left];
            if(sum == 0){
                arr.push([nums[i],nums[left],nums[right]]);
                while(left<right && nums[left] == nums[left+1]) left++;
                while(left<right && nums[right] == nums[right-1])right--;
                left++;
                right--;
            }else if(sum < 0){
                left++
            }else if(sum > 0){
                right--
            }
        }
    }
    return arr
}

力扣42.接雨水

解题思路:按照列来累加每个列的雨水高度,其实某一列的雨水高度就是此列左侧最高列和右侧最高列中最矮的那个列的高度减去此列的高度,分别记录每一列的左最高和右最高,遍历累加即可

/**
/**
 * @param {number[]} height
 * @return {number}
 */
var trap = function(height) {
    const len = height.length;
    if(len <= 2) return 0;
    let maxLeft = [];
    let maxRight = [];
    // 记录每个柱子左边柱子最大高度
    maxLeft[0] = height[0];
    for(let i = 1; i < len; i++){
        maxLeft[i] = Math.max(height[i], maxLeft[i - 1]);
    }
    // 记录每个柱子右边柱子最大高度
    maxRight[len - 1] = height[len - 1];
    for(let i = len - 2; i >= 0; i--){
        maxRight[i] = Math.max(height[i], maxRight[i + 1]);
    }
    // 求和
    let sum = 0;
    for(let i = 0; i < len; i++){
        let count = Math.min(maxLeft[i], maxRight[i]) - height[i];
        if(count > 0) sum += count;
    }
    return sum;
};