[剑指offer]和为S的两个数字

Posted moonbeautiful

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[剑指offer]和为S的两个数字相关的知识,希望对你有一定的参考价值。

题目描述

输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。

输出描述:

对应每个测试案例,输出两个数,小的先输出。




题目链接:
https://www.nowcoder.com/practice/390da4f7a00f44bea7c2f3d19491311b?tpId=13&tqId=11195&tPage=3&rp=3&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking



package com.sunshine.OFFER66_SECOND;

import org.junit.Test;

import java.util.ArrayList;

public class A42_FindNumbersWithSum 

    @Test
    public void test() 
        int[] arr = 1, 2, 3, 4;
        ArrayList<Integer> arrayList = FindNumbersWithSum(arr, 5);
        arrayList.forEach(a -> System.out.print(a + " "));
        ArrayList<Integer> arrayList1 = FindNumbersWithSum2(arr, 5);
        arrayList1.forEach(a -> System.out.print(a + " "));
    

    public ArrayList<Integer> FindNumbersWithSum(int[] array, int sum) 
        if (array.length < 2) 
            return new ArrayList<>();
        
        ArrayList<Integer> ans = new ArrayList<>();
        int ans1 = 0;
        int ans2 = 0;
        for (int j = 0; j < array.length; j++) 
            for (int i = j + 1; i < array.length; i++) 
                if (array[i] + array[j] == sum) 
                    if (ans.isEmpty() || ans1 * ans2 > array[i] * array[j]) 
                        ans1 = array[j];
                        ans2 = array[i];
                        ans.add(ans1);
                        ans.add(ans2);
                    
                 else if (array[i] + array[j] > sum) 
                    break;
                
            
        
        return ans;
    
    //其他人解。
    //两端夹逼,两数差越大积越小,所以找到的第一个和为sum的两数即为答案。
    //此时我产生了一个疑问,left右移数值增大,right左移数值减小,同时left左移也是减小,right右移也是增大啊,是怎么排除的?
    //后来终于想通了。
    //举例:
    // a,b,c,d,e,f
    // b+e>sum   ->    b+d>sum  那么,b与d及其右边的数所有和都大于sum,疑问来了:left左移和right左移都会使和减小,为什么只需判断right左移的情况呢?
    // b+e>sum   ->    b+d<sum  那么,b一定不是答案之一,右移
    //疑问:a<b,b+d>sum,那么a+d呢?是不是遗漏了?
    //解:a+d<sum,因为a->b的原因是 a+(大于d的一个数)<sum 导致left右移。
    public ArrayList<Integer> FindNumbersWithSum2(int[] array, int sum) 
        if (array.length < 2) 
            return new ArrayList<>();
        
        int left = 0;
        int right = array.length - 1;
        ArrayList<Integer> ans = new ArrayList<>();
        while (left < right) 
            if (array[left] + array[right] == sum) 
                ans.add(array[left]);
                ans.add(array[right]);
                break;
            else if(array[left] + array[right] > sum)
                right--;
            else
                left++;
            
        
        return ans;
    

 

 

以上是关于[剑指offer]和为S的两个数字的主要内容,如果未能解决你的问题,请参考以下文章

[剑指Offer]41 和为S的两个数字 VS 和为S的连续正数序列

剑指offer 42.和为S的两个数字

剑指 Offer 57. 和为s的两个数字

剑指offer---和为S的两个数字

剑指 Offer 57. 和为s的两个数字

剑指offer系列45---和为s的两个数字