数据结构与算法每日一题——快慢指针(15. 三数之和)

85 阅读1分钟

15. 三数之和

/**
 * @param {number[]} nums
 * @return {number[][]}
 */
var threeSum = function (nums) {
    //结果数组
    let ans = [];
    // 数组长度
    const len = nums.length;
    if (nums == null || len < 3) return ans;
    // 因为不需要返回下标 可以排序
    nums.sort((a, b) => a - b); // 排序
    for (let i = 0; i < len; i++) {
        if (nums[i] > 0) break; // 如果当前数字大于0,则三数之和一定大于0,所以结束循环
        if (i > 0 && nums[i] == nums[i - 1]) continue; // 去重
        let L = i + 1;
        let R = len - 1;
        while (L < R) {
            const sum = nums[i] + nums[L] + nums[R];
            if (sum == 0) {
                ans.push([nums[i], nums[L], nums[R]]);
                while (L < R && nums[L] == nums[L + 1]) L++; // 去重
                while (L < R && nums[R] == nums[R - 1]) R--; // 去重
                L++;
                R--;
            }
            else if (sum < 0) L++;
            else if (sum > 0) R--;
        }
    }
    return ans;

    // let result =[]
    // let len = nums.length
    // // 给数组排序
    // nums = nums.sort((a, b) => a - b);
    // // // 遍历数组 0到 lenght-2
    // for(let i=0;i<len;i++){
    //     // 如果当前数字等于前一个数字 则跳过
    //     if(i===0 || nums[i]!=nums[i-1]){
    //         let start =i+1, end =len-1
    //         while(start<end){
    //             // 如果数字不同 start=i+1 end =len-1 查看i start end 三数之和和0进行比较 小于0 则start++ 大于0 则end--
    //             let sum = nums[i]+nums[start]+nums[end]
    //             if(sum===0){
    //                 result.push(nums[i],nums[start],nums[end])
    //                 start++
    //                 end--
    //                 while(start<end && nums[start]===nums[start+1]){start ++}
    //                 while(start<end && nums[end]===nums[end-1]){end--}
    //             }else if(sum < 0){
    //                 start++
    //             }else{
    //                 end--
    //             }
    //         }
    //     }
    // }
    // return result

    // 最左侧值为定值,右侧所有值进行两边推进计算
    // let res = [];
    // nums.sort((a, b) => a - b);
    // let size = nums.length;
    // if (nums[0] <= 0 && nums[size - 1] >= 0) {
    //     // 保证有正数负数
    //     let i = 0;
    //     while (i < size - 2) {
    //         if (nums[i] > 0) break; // 最左侧大于0,无解
    //         let first = i + 1;
    //         let last = size - 1;
    //         while (first < last) {
    //             if (nums[i] * nums[last] > 0) break; // 三数同符号,无解
    //             let sum = nums[i] + nums[first] + nums[last];
    //             if (sum === 0) {
    //                 res.push([nums[i], nums[first], nums[last]]);
    //             }
    //             if (sum <= 0) {
    //                 // 负数过小,first右移
    //                 while (nums[first] === nums[++first]) { } // 重复值跳过
    //             } else {
    //                 while (nums[last] === nums[--last]) { } // 重复值跳过
    //             }
    //         }
    //         while (nums[i] === nums[++i]) { }
    //     }
    // }
    // return res;
};