• leetcode-1 Two Sum 找到数组中两数字和为指定和


    

    问题描写叙述:在一个数组(无序)中高速找出两个数字,使得两个数字之和等于一个给定的值。如果数组中肯定存在至少一组满足要求。

    《剑指OfferP214(有序数组) 《编程之美》P176

    Que:Given an array of integers, find twonumbers such that they add up to a specific target number.

    The function twoSum should return indices ofthe two numbers such that they add up to the target, where index1 must be lessthan index2. Please note that your returned answers (both index1 and index2)are not zero-based.

    You may assume that each input would haveexactly one solution.

    Input: numbers={2, 7, 11, 15}, target=9
    Output: index1=1, index2=2

     

    一、暴力穷举法 时间复杂度:O(N^2)

    代码:

    // 暴力解法。时间复杂度(O(n^2)),性能太差无法通过
    	public int[] twoSum1(int[] numbers, int target) {
    		if (numbers != null) {
    			int i, j = 0;
    			for (i = 0; i < numbers.length; i++) {
    				for (j = i + 1; j < numbers.length; j++) {
    					if (numbers[i] + numbers[j] == target) {
    						int[] result = { ++i, ++j };
    						return result;
    					}
    				}
    			}
    		}
    		return null;
    	}
    


    二、Hash表法,以空间换时间:时间复杂度:O(N)空间复杂度O(N)

    更快的查找方法:hash表,给定一个数字,依据hash映射查找还有一个数字是否在数组中,仅仅需O1)的时间,但须要承担O(N)hash表存储空间。

    C++能够使用STL中的hash_map,java使用HashMap

    代码:

    // 使用HashMap(查找的时间复杂度为O(1))
    	// 由题目如果知仅仅有一对数满足该情况,故每一个数都是唯一的,不存在重数的情况
    	public int[] twoSum2(int[] numbers, int target) {
    		if (numbers != null) {
    			// 由于Hashmap仅提供通过key获得value,故
    			// HashMap value放置与numers[index]匹配的数值,key放置index;,故
    			// 在以下循环时每一次查询map中的value是否有相等的值。有即相互匹配
    			// 其思想在于用index的value表示数组中的该数据,map中的key与之匹配,并在数组中寻找匹配值
    			HashMap<Integer, Integer> num_map = new HashMap<>();
    			for (int i = 0; i < numbers.length; i++) {
    				if (num_map.containsKey(numbers[i])) {
    					int index = num_map.get(numbers[i]);
    					int[] result = { ++index, ++i };
    					return result;
    				} else {
    					num_map.put(target - numbers[i], i);
    				}
    			}
    		}
    		return null;
    	}
    
    

    三、非常easy能够想到先将查找的数组排序,然后用二分查找等方法进行查找。本题中能够直接对两个数字的和进行一个有序的遍历(当然和不用所有真正计算出来)。

    1.首先对数组进行排序。时间复杂度为O(NlogN)

    2.然后从i=0,j=end開始和末位的两个数字開始。计算两个之和sum。若sum大于目标值target,则须要一个较小的因子,j--;反之,i++;直至找到终于的结果。

    代码:(这里没有返回相应原始位置。仅仅是返回了两个相应数据)

    public int[] twoSum3(int[] numbers, int target) {
    		if (numbers != null) {
    			// 先进行排序,这里使用归并排序
    			new Merge_Sort().Merge_Sort(numbers, new int[numbers.length], 0,
    					numbers.length - 1);
    			// 实现该查找算法
    			int ahead = numbers.length - 1;
    			int behind = 0;
    			while (ahead > behind) {
    				// 注意result和要考虑两个较大int相加溢出的问题
    				long result = numbers[ahead] + numbers[behind];
    
    				if (result == target) {
    					int[] sum = { numbers[behind] , numbers[ahead] };
    					//假设要返回两个原始位置值,是否意味着还是又一次进行两次查询;
    					return sum;
    				}
    
    				if (result < target) {
    					behind++;
    				} else {
    					ahead--;
    				}
    			}
    		}
    
    		return null;
    	}
    



  • 相关阅读:
    符瑞艺 160809228_C语言程序设计实验2 选择结构程序设计
    页面布局class常见命名规范
    CSS学习笔记
    HTML学习笔记
    虚拟机Centos7设置ip地址,并ping真机ip
    vue单页面开发和多页面开发的概念,及优缺点?
    传统的DOM渲染方式?
    面试题
    通过电脑chrome调试手机真机打开的微信H5页面,调试电脑微信H5页面(转载自 乐乐熊小妹)
    常见前端面试题及答案
  • 原文地址:https://www.cnblogs.com/blfshiye/p/5211161.html
Copyright © 2020-2023  润新知