【双指针】-- 和为 S 的两个数字

题目:

在有序数组中找出两个数,使得和为给定的数 S。如果有多对数字的和等于 S,输出两个数的乘积最小的。

分析

  • 乘积最小的规律是:两个数的差尽可能大。
  • 要找两个数字,而且是数组,第一感觉就是双指针的策略

思路

使用双指针,一个指针指向元素较小的值,一个指针指向元素较大的值。
指向较小元素的指针从头向尾遍历,指向较大元素的指针从尾向头遍历。

  • 如果两个指针指向元素的和 sum == target,那么这两个元素即为所求。
  • 如果 sum > target,移动较大的元素,使 sum 变小一些,positionBig变小一些;
  • 如果 sum < target,移动较小的元素,使 sum 变大一些,positionSmall 变大一些;

1.如果 sum > target,移动较大的元素,使 sum 变小一些,为什么不是positionSmall 变小一些,而是positionBig变小一些?
如果positionSmall在首位,是没办法小的,只能positionBig变小
2.同理 如果 sum < target,移动较小的元素,使 sum 变大一些,为什么不是positionBig 变大一些,而是positionSmall 变大一些?
同理,如果positionBig在末尾,是没办法变大,只能positionSmall变大

在这里插入图片描述


源码

package org.example.pointer;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * 和为 S 的两个数字
 * @author Abner G
 * @date 2022/5/12 20:18
 */
public class practicePointer01 {

    /**
     * 题目
     * 在有序数组中找出两个数,使得和为给定的数 S。
     * 如果有多对数字的和等于 S,输出两个数的乘积最小的
     * https://github.com/CyC2018/CS-Notes/blob/master/notes/57.1%20%E5%92%8C%E4%B8%BA%20S%20%E7%9A%84%E4%B8%A4%E4%B8%AA%E6%95%B0%E5%AD%97.md
     *
     */

    public static void main(String[] args) {
        int[] test={1, 3, 4,5, 6, 8, 9};

        ArrayList<Integer> integers = FindNumbersWithSum(test, 11);

        System.out.println(integers);

    }


    /**
     *
     *  题点:两个数的乘积最小,说明想要最两边的一组
     *  使用双指针,一个指针指向元素较小的值,一个指针指向元素较大的值。
     *  指向较小元素的指针从头向尾遍历,指向较大元素的指针从尾向头遍历。
     *
     *  如果两个指针指向元素的和 sum == target,那么这两个元素即为所求。
     *  乘积最小的规律是:两个数的差尽可能大。
     *  如果 sum > target,移动较大的元素,使 sum 变小一些,positionBig变小一些;
     *  如果 sum < target,移动较小的元素,使 sum 变大一些,positionSmall 变大一些;
     *
     *  可能死脑经的点:
     *  1.如果 sum > target,移动较大的元素,使 sum 变小一些,为什么不是positionSmall 变小一些,而是positionBig变小一些?
     *  如果positionSmall在首位,是没办法小的,只能positionBig变小
     *  2.同理 如果 sum < target,移动较小的元素,使 sum 变大一些,为什么不是positionBig 变大一些,而是positionSmall 变大一些?
     *  同理,如果positionBig在末尾,是没办法变大,只能positionSmall变大
     */

    public static ArrayList<Integer> FindNumbersWithSum(int[] nums,int target){
        int i=0;
        int j=nums.length-1;

        while (i<j){
            int sum = nums[i] + nums[j];
            if (sum==target){
                return new ArrayList<>(Arrays.asList(nums[i],nums[j]));
            }
            if (sum<target){
                i++;
            }else {
                j--;
            }
        }
        return null;
    }


}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Abner G

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值