算法笔记_037:寻找和为定值的两个数(Java)

目录

1 问题描述

2 解决方案

2.1 排序夹逼法

 


1 问题描述

输入一个整数数组和一个整数,在数组中查找两个数,满足他们的和正好是输入的那个整数。如果有多对数的和等于输入的整数,输出任意一对即可。例如,如果输入数组[1,2,4,5,7,11,15]和整数15,那么由于4+11 = 15,因此输出4和11。


2 解决方案

2.1 排序夹逼法

首先将整数数组,使用合并排序进行从小打到的排序,然后对这个排完序的数组从两头往中间遍历,一旦出现两个数的和等于输入的那个整数,则立即输出这两个数,并结束遍历。

具体代码如下:

package com.liuzhen.array_2;

public class TwoSumN {
    /*
     * 参数A:给定的一个从小到大排序的数组
     * 参数n:待求和数n
     * 函数功能:打印出A中两个元素,满足A[i]+A[j] = n
     */
    public void getTwoSumN(int[] A,int n){
        int start = 0;
        int end = A.length - 1;
        while(start < end){
            if(A[start] + A[end] == n){
                System.out.println("\n数组中元素A["+start+"]" +
                        " + A["+end+"] = "+n+",A["+start+"] = "+A[start]+",A["+end+"] = "+A[end]);
                break;
            }
            else{
                if(A[start] + A[end] > n)
                    end--;
                else
                    start++;
            }
        }
    }

    //归并排序
        public void mergeSort(int[] A){
            if(A.length > 1){
                int[] leftA = getHalfArray(A,0);   //数组A的左半部分
                int[] rightA = getHalfArray(A,1);  //数组A的右半部分
                mergeSort(leftA);
                mergeSort(rightA);
                getMerge(A,leftA,rightA);
            }
        }

        /*
         * 参数A:要进行折半的数组
         * 参数judge:judge == 0表示返回数组A左上半部分,judge != 0表示返回数组A的右半部分
         * 函数功能:把数组按照长度均分为上半部分和下半部分
         */
        public int[] getHalfArray(int[] A,int judge){
            int[] result;
            if(judge == 0){
                result = new int[A.length/2];
                for(int i = 0;i < A.length/2;i++)
                    result[i] = A[i];
            }
            else{
                result = new int[A.length - A.length/2];
                for(int i = 0;i < A.length - A.length/2;i++)
                    result[i] = A[i+A.length/2];
            }
            return result;
        }
        /*
         *参数A:给定待排序数组
         *参数leftA:数组A的左半部分
         *参数rightA:数组的右半部分
         *函数功能:返回数组A的从小到大排序
         */
        public void getMerge(int[] A,int[] leftA,int[] rightA){
            int i = 0;       //用于计算当前遍历leftA的元素个数
            int j = 0;       //用于计算当前遍历rightA的元素个数
            int count = 0;   //用于计算当前得到按从小到大排序的A的元素个数
            while(i < leftA.length && j < rightA.length){
                if(leftA[i] < rightA[j]){
                    A[count++] = leftA[i];
                    i++;
                }
                else{
                    A[count++] = rightA[j];
                    j++;
                }
            }
            if(i < leftA.length){
                while(i < leftA.length)
                    A[count++] = leftA[i++];
            }
            if(j < rightA.length){
                while(j < rightA.length)
                    A[count++] = rightA[j++];
            }
        }

        public static void main(String[] args){
            TwoSumN test = new TwoSumN();
            int[] A = {2,1,7,4,6,1,2,4,3,6,8,4,2,1,7,3,4,6,8,3,4};
            test.mergeSort(A);
            System.out.println("对数组A进行合并排序后结果:");
            for(int i = 0;i < A.length;i++)
                System.out.print(A[i]+" ");
            test.getTwoSumN(A, 10);
        }
}

运行结果;

对数组A进行合并排序后结果:
1 1 1 2 2 2 3 3 3 4 4 4 4 4 6 6 6 7 7 8 8
数组中元素A[3] + A[20] = 10,A[3] = 2,A[20] = 8
时间: 2024-10-20 22:04:39

算法笔记_037:寻找和为定值的两个数(Java)的相关文章

编程之法:面试和算法心得(寻找和为定值的多个数)

内容全部来自编程之法:面试和算法心得一书,实现是自己写的使用的是java 题目描述 输入两个整数n和sum,从数列1,2,3.......n 中随意取几个数,使其和等于sum,要求将其中所有的可能组合列出来. 分析与解法 解法一 注意到取n,和不取n个区别即可,考虑是否取第n个数的策略,可以转化为一个只和前n-1个数相关的问题. 如果取第n个数,那么问题就转化为"取前n-1个数使得它们的和为sum-n",对应的代码语句就是sumOfkNumber(sum - n, n - 1): 如果

寻找和为定值的两个数

1. 题目描述 给定一个数组(无序或者有序,两种情况都要考虑),找出和为M的两个数.最多时间复杂度能有多少? https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/02.02.md 2. 数组有序--两端指针扫描法 数组有序的情况,在时间复杂度上我们就省去了排序的O(NlogN). 我们使用两端指针扫描法是比较简单的,时间复杂度为O(N), 空间复杂度为O(1).如下图所示: 首先我们在

寻找和为定值的多个数

1.首先看看简单的,寻找和为定值的2个数求解 采用HASH方式就可以求解. 具体参考这个文章: 寻找和为定值的2个数 2.那寻找和为定值的多个数怎么求解了 #include <stdio.h> #include <stdlib.h> /*原题:输入两个整数 n 和 m,从数列1,2,3.......n 中随意取几个数,使其和等于 m ,要求将其中所有的可能组合列出来 修改之后改为:对任意一个数组寻找m个数,使其和为指定的值*/ void findSubSum(int* a, int

编程之法section II: 2.2 和为定值的两个数

====数组篇==== 2.2 求和为定值的两个数: 题目描述:有n个整数,找出其中满足两数相加为target的两个数(如果有多组满足,只需要找出其中一组),要求时间复杂度尽可能低. 解法一: 思路:开散列映射,空间换时间, 查找耗时o(n) Writer: zzq Function: 求和为定值的两个数. 方法一: 开散列映射(哈希表). 1) 用哈希表Hashmap先把数组中的数字和对应的下标进行存储,(键,值)=(具体数值,对应下标): 2) 遍历数组,对loss=target-nums[

【剑指offer学习】求和为定值的两个数(拓展)

接着上面一篇文章: http://blog.csdn.net/u013476464/article/details/40651451 接下来我们拓展一下题目,如果数组是乱序的,并且规定数组中的元素所有为非负整数,相同给定一个数sum,在数组中找出随意两个数,使二者的和为sum. 分析: 由于题目中限定了数组中的元素为非负整数,因此我们能够用哈希数组,开辟一个长度为sum的bool数组B[sum],并所有初始化为false,对数组A进行一次遍历,假设当前的元素A[i]大于sum,则直接跳过,否则,

和为定值的两个数

题目描述: 输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的. 输入: 每个测试案例包括两行: 第一行包含一个整数n和k,n表示数组中的元素个数,k表示两数之和.其中1 <= n <= 10^6,k为int 第二行包含n个整数,每个数组均为int类型. 输出: 对应每个测试案例,输出两个数,小的先输出.如果找不到,则输出“-1 -1” 样例输入: 6 15 1 2 4 7 11 15 样例输出: 4 11     思

【剑指offer学习】求和为定值的两个数

<神雕侠侣>中的'剑冢',收存着'剑魔独孤求败'生平用过的三把剑:"杨过提起右首第一柄剑,只见剑下的石上刻有两行小字'凌厉刚猛,无坚不摧,弱冠前以之与河朔群雄争锋':第二把是玄铁重剑:'重剑无锋,大巧不工.四十岁前恃之横行天下':第三把则是木剑,剑下的石刻道:'四十岁后,不滞于物,草木竹石均可为剑.自此精修,渐进于无剑胜有剑之境.'.算法的精髓也在于此,只有突破一层层境界,才能有所突破. 题目描述: 输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有

[算法]寻找和为定值的多个数

2010 年中兴面试题 编程求解: 输入两个整数n 和m,从数列1,2,3.......n 中随意取几个数, 使其和等于m ,要求将其中所有的可能组合列出来. // 21 题递归方法 //[email protected] July && yansha //July.yansha,updated. #include<list> #include<iostream> using namespace std; list<int>list1; void fin

算法笔记_077:蓝桥杯练习 K好数(Java)

目录 1 问题描述 2 解决方案   1 问题描述 问题描述 如果一个自然数N的K进制表示中任意的相邻的两位都不是相邻的数字,那么我们就说这个数是K好数.求L位K进制数中K好数的数目.例如K = 4,L = 2的时候,所有K好数为11.13.20.22.30.31.33 共7个.由于这个数目很大,请你输出它对1000000007取模后的值. 输入格式 输入包含两个正整数,K和L. 输出格式 输出一个整数,表示答案对1000000007取模后的值. 样例输入 4 2 样例输出 7 数据规模与约定