【前端经典算法题】给定一个数组nums和目标值target,找两数之和、三数之和为目标值的数

前言

前端算法题不仅可以提升开发者的编程能力和解决问题的能力,还有助于提高面试竞争力,并优化代码性能。因此,掌握并熟练应用算法题对于前端开发者来说具有重要的意义。

今天给大家带来两道经典算法题。

1、两数之和

题目: 给定一个数组 nums 和一个目标值 target,在该数组中找出和为目标值的两个数

输入: nums: [8, 2, 6, 5, 4, 1] ; target:11

输出: [6, 5]

方法一:简单粗暴双重for循环

    function findSum(nums, target) {
        let arr = []
        for(let i = 0; i < nums.length; i++) {
            for(let j = i+1; j < nums.length; j++) {
                if(nums[i] + nums[j] === target) {
                    arr.push(nums[i], nums[j])
                    return arr
                }
            }   
        }
    }
    const sum = findSum(nums, target)
    console.log(sum);

方法二:新建数组/对象进行对比,减少一重循环

    function findSum(nums, target) {
        let numsMap = []
        for(let i = 0; i < nums.length; i++) {
        // 遍历数组,判断 numsMap 是否含有这个目标值-当前数值
        // 有直接返回,没有的话放到 numsMap 里面
            const diff = target - nums[i]
            if (numsMap.find(item => item === diff)) {
                return [diff, nums[i]]
            }
            numsMap.push(nums[i])
        }
    }
    const sum = findSum(nums, target)
    console.log(sum);

2、三数之和

题目: 给定一个数组nums,判断 nums 中是否存在三个元素a,b,c,使得 a + b + c = target,找出所有满足条件且不重复的三元组合

输入: nums: [1,1,2,2,3,3,4,5,5,6] ;target:7

输出: [[1, 1, 5], [1, 2, 4], [1, 3, 3], [2, 2, 3]]

方法:双指针法

具体步骤:

  1. 首先对数组进行排序,这样可以方便处理重复元素和判断三个数的大小关系。
  2. 使用外层循环固定一个数,假设为 nums[i]。内层循环使用两个指针,一个从 i+1 开始,一个从数组末尾开始,分别为 left 和 right
  3. 判断 nums[i] + nums[left] + nums[right] 是否等于 target
  4. 如果相等,则将 [nums[i], nums[left], nums[right]] 加入结果集,并同时将 left 和 right 各移动一位。同时需要考虑去重,跳过相同的元素。
  5. 如果和小于 target,则将 left 向右移动一位,使得和增大。
  6. 如果和大于 target,则将 right 向左移动一位,使得和减小。
  7. 继续重复步骤 3,直到 left 和 right 相遇,此时结束内层循环。
  8. 继续外层循环,固定下一个数,重复步骤 2 至 4,直至遍历完整个数组。

最终得到的结果集即为所有满足条件且不重复的三元组合。

    const nums = [1, 1, 2, 2, 3, 3, 4, 5, 5, 6]
    const target = 7

    function threeSum(nums, target) {
        let result = [];

        if (nums.length < 3) {
            return result;
        }

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

        for (let i = 0; i < nums.length - 2; i++) {
            // 跳过重复的固定数
            if (i > 0 && nums[i] === nums[i - 1]) {
                continue;
            }

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

            while (left < right) {
                let 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;
    }

    const result = threeSum(nums, target);
    console.log(result);

猜你喜欢

转载自blog.csdn.net/weixin_42373175/article/details/131399126