返回

揭秘双指针算法:用数学直觉解决三数、四数之和

前端

双指针算法是一种解决特定类型问题的算法,它利用了线性结构(如数组)的遍历特性和数学直觉。在双指针算法中,通常使用两个指针变量在数组中移动,根据某些特定条件进行比较和更新操作,从而高效地解决问题。

双指针的奥秘:数学直觉

双指针算法的奥秘之一在于其巧妙地利用了数学直觉。通过将数组看作一个数学空间,并利用指针变量作为坐标,算法可以根据数学规律和空间关系来进行操作。这种数学思维方式使双指针算法能够以一种优雅且高效的方式解决问题。

三数之和:基础入门

三数之和问题要求给定一个数组和一个目标值,找出数组中三个数的和等于目标值的组合。双指针算法通过设置两个指针,一个指向数组头部,另一个指向尾部,然后根据和的大小调整指针位置。当和大于目标值时,尾指针向左移动,当和小于目标值时,头指针向右移动。

// 三数之和
function threeSum(nums: number[], target: number): number[][] {
    if (!nums || nums.length < 3) {
        return [];
    }

    nums.sort((a, b) => a - b);

    const result: number[][] = [];

    for (let i = 0; i < nums.length; i++) {
        if (i > 0 && nums[i] === nums[i - 1]) {
            continue;
        }

        let left = i + 1;
        let right = nums.length - 1;

        while (left < right) {
            const sum = nums[i] + nums[left] + nums[right];

            if (sum === target) {
                result.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 < target) {
                left++;
            } else {
                right--;
            }
        }
    }

    return result;
}

四数之和:进一步探索

四数之和问题是三数之和的扩展,要求找到数组中四个数的和等于目标值的组合。双指针算法可以再次派上用场,但需要对三数之和的思路进行扩展。

// 四数之和
function fourSum(nums: number[], target: number): number[][] {
    if (!nums || nums.length < 4) {
        return [];
    }

    nums.sort((a, b) => a - b);

    const result: number[][] = [];

    for (let i = 0; i < nums.length - 3; i++) {
        if (i > 0 && nums[i] === nums[i - 1]) {
            continue;
        }

        for (let j = i + 1; j < nums.length - 2; j++) {
            if (j > i + 1 && nums[j] === nums[j - 1]) {
                continue;
            }

            let left = j + 1;
            let right = nums.length - 1;

            while (left < right) {
                const sum = nums[i] + nums[j] + nums[left] + nums[right];

                if (sum === target) {
                    result.push([nums[i], nums[j], 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 < target) {
                    left++;
                } else {
                    right--;
                }
            }
        }
    }

    return result;
}

双指针算法不仅仅是一种解决特定问题的技术,它更是一种思维方式。它教会我们用数学直觉和结构化思维来解决复杂的问题。双指针算法的精髓在于其简洁性和效率,它在各种领域都有着广泛的应用,包括数据结构、算法设计和优化问题。