经典算法学习——快速找出数组中两个数字,相加等于某特定值

这个算法题的描述如下:快速找出一个数组中的两个数字,让这两个数字之和等于一个给定的值。目前我假设数组中的都是各不相等的整数。这道题是我在一次面试中被问到的,由于各种原因,我没回答上来,十分尴尬。其实这道题十分简单,我们使用相对巧妙的方法来实现下。注意不使用两层循环的元素遍历。示例代码上传至:https://github.com/chenyufeng1991/SumTo100

算法描述如下:

(0)首先对原数组进行排序,成为递增数组;

(1)对排序后的数组头部i [0]和数组尾部j [n-1]相加,判断是否等于100,等于100则打印,然后执行(3),否则执行(2);

(2)如果相加小于100,则i++,j不变。如果相加大于100,则i不变,j--;继续执行(1);

(3)数组下标i++,j--,继续执行(1);

(4)当i==j,退出程序。

代码实现如下:

//
//  main.c
//  SumTo100
//
//  Created by chenyufeng on 16/2/5.
//  Copyright © 2016年 chenyufengweb. All rights reserved.
//

#include <stdio.h>

/**
 *  要求找出数组中两个数相加为100的所有组合;我先假设里面的的数字两两不相等;
 */

void findSumTo100(int *a,int n);

int main(int argc, const char * argv[]) {

    //原始数组;
    int a[] = {55,50,99,80,1,30,70};
    /**
     *  首先对这个数组进行排序,下面是排序后的结果;
     */
    int a_sort[] = {1,30,50,55,70,80,99};
    findSumTo100(a_sort,7);

    return 0;
}
/**
 *  简单的算法是这样的:
(1) 对排序后的数组头部i [0]和数组尾部j [n-1]相加,判断是否等于100,等于100则打印,然后执行(3),否则执行(2);
 (2)如果相加小于100,则i++,j不变。如果相加大于100,则i不变,j--;继续执行(1)
 (3)数组下标i++,j--,继续执行(1);
 (4)当i==j,退出程序。
 */
void findSumTo100(int *a,int n){
    for (int i = 0,j = n - 1; i != j; ) {

        int sum = a[i] + a[j];
        if (sum == 100) {
            printf("%d %d\n",a[i],a[j]);
            i++;
            j--;
        }
        else if (sum < 100){
            i++;
        }
        else if (sum > 100){
            j--;
        }
    }
}
时间: 2024-12-26 02:59:50

经典算法学习——快速找出数组中两个数字,相加等于某特定值的相关文章

【编程题目】找出数组中两个只出现一次的数字 ★★(自己没做出来)

61.找出数组中两个只出现一次的数字(数组)题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字.要求时间复杂度是 O(n),空间复杂度是 O(1). 思路:瞄到了一眼提示,说是位运算. 根据异或的运算性质: a ⊕ b ⊕ a = b 把所有的数字都异或一遍得到的结果就是 那两个只出现一次的数字异或的结果. 可怎么分出那两个数字就卡住了. 看了下网上答案,要根据得到的异或值把数字分为两组,再对每一组异或就可以得到这两个数字了! 代码如下: /* 61

找出数组中两数之和为指定值的所有整数对

一,问题描述 给定一个整型数组(数组中的元素可重复),以及一个指定的值.打印出数组中两数之和为指定值的 所有整数对 二,算法分析 一共有两种方法来求解.方法一借助排序,方法二采用HashSet 方法一: 先将整型数组排序,排序之后定义两个指针left和right.left指向已排序数组中的第一个元素,right指向已排序数组中的最后一个元素 将 arr[left]+arr[right]与 给定的元素比较,若前者大,right--:若前者小,left++:若相等,则找到了一对整数之和为指定值的元素

找出数组中重复的数字(c语言)

让人瑟瑟发抖的面试题... 来我们看一下题目在一个 长度为n的数组里的所有数字都在0~n-的范围内.数组中某些数字是重复的,但不知道有几个数字重复伦理,也不知道每个数字重复了多少次,找出任意一个重复的数字注意:时间复杂度O(n),空间复杂度O(1) 怎么解决勒???分析:利用题目中0~n-1范围,可以运用数组下标和数组内容进行比较if (arr[i] != arr[arr[i]]),如果不相等时,进行调换,相等时,直接返回值来看看代码 #include<stdio.h> #define SIZ

面试题---找出数组中两个只出现一次的数

题目描述:给一个数组,里面有两个数只出现一次,其它的数都出现两次,请找出这两个数: 样例:输入 2 4 2 7 4 9 输出 7 9 思路:假定要找出的这两个数为x.y   把所有的数异或,结果是x与y异或的值,那么肯定不为0,那么这个值的二进制至少有一位为1,也就是说x和y的二进制在这一位上必定一个为0,一个为1,那么可以根据这一位把这个数组分成两个数组,x和y在不同的数组里,接下来对每个数组直接异或出的值就是结果了: 代码如下: #include <iostream> #include &

找出数组中两个只出现一次的数字!

实现代码: 1.PHP实现: <?php     $arr=array(1,1,5,3,2,2);          //因为每个元素都需要分别和其他的元素进行比较     //所以需要双重循环     for($i=0;$i<count($arr);$i++){                  for($j=0;$j<count($arr);$j++){                      //此处目的是避免数组元素和自己进行比较             if($i != $j

找出数组中两个只出现一次的数字

题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次.请写程序找出这两个只出现一次的数字.要求时间复杂度是O(n),空间复杂度是O(1). 还是理解不够深刻. 这题的主要思路还是之前的数组中只出现一次的数字的那种模式,一次遍历加上异或运算.那么这个异或的值肯定是这两个只出现一次的数字的相异或的值.那么这个值的二进制表现形式中的1的结果就表示这两个数字在该bit位上不一样.那么通过此举,我们可以以这个bit位是否为1来从整个数组中把这两个只出现一次的数字分开. 通过此举,别的出现两次的数字

找出数组中两个只出现一次的数字 【微软面试100题 第六十一题】

题目要求: 一个整型数组里除了两个数字机之外,其他的数字都出现了两次. 请写程序找出这两个只出现一次的数字.要求时间复杂度O(N).空间复杂度O(1). 参考资料:剑指offer第40题. 题目分析: 已知: 1.两个相同的数字异或的结果为0,即a^a = 0. 2.两个不相同的数字异或的结果的二进制中某一位为1,则这两个数字的二进制中对应位一个为0,一个为1.如3^2 = 1,对于最低位的二进制,3的最低位二进制为1,2的最低位二进制位0,则结果1的最低位二进制肯定为1. 假设原数组中只出现一

找出数组中特定和数字下标(JAVA)

比如: 输入: numbers={2, 7, 11, 15}, target=9 输出: index1=1, index2=2 1 public class _003TwoSum { 2 3 public static void main(String[] args) { 4 int a[]={3,22,4,7,8,22}; 5 6 display(twoSum3(a,30)); 7 } 8 //暴力搜索法 9 public static int[] twoSum(int[] numbers,

算法之找出数组中出现次数大于n/m的元素

最经典的题目莫过于是: 在一个数组中找出出现次数超过n/2的元素?更进一步的,找出数组中出现次数大于n/3的所有元素? 注:这里有一个很重要的事实,那就是出现次数大于n/m的元素的个数至多为(m-1)个,比如出现次数大于n/3的至多只有两个. 关于这一类题目的解题思路,可以先讲一个游戏 称作 "俄罗斯方块".这里的规则是每一行的元素要完全不一样,一样的元素则总是在同一列,如果最下面的行已经被填满,那么消除最下面的行. 例如在数组 A = {7,3,3,7,4,3,4,7,3,4,3,4