从一组数据中找出和为给定值的数的两个数的下标(找出一组或者所有组合)twoSums

package LeetCode;

import java.util.ArrayList;
import java.util.HashMap;
class node{
	int index1;
	int index2;
}
public class twoSums {
	ArrayList<node> nodeArr = new ArrayList<node>();
	/**
	 *  Given an array of integers, find two numbers such that they 
	 *  add up to a specific target number.
		The function twoSum should return indices of the two numbers 
		such that they add up to the target, where index1 must be less 
		than index2. Please note that your returned answers (both index1 and index2)
		 are not zero-based.
		You may assume that each input would have exactly one solution.
		Input: numbers={2, 7, 11, 15}, target=9
		Output: index1=1, index2=2
	 * @param numbers
	 * @param target
	 * @return
	 */
	/***
	 * 主要思路:当看到题目时我们首先考虑到的肯定是一个二层循环,这样是可以找到找到结果的,但是这样下来的话时间复杂度会比较高,为O(n^2)。
	 * 所以为了降低时间复杂度我们可以考虑用hashMap的去重性来做。这样我们一次遍历就解决问题了,每次我们遍历的时候就去判断
	 * map.containsKey(target - numbers[i]),如果有,则表示前面已经存在一个相加等于target的元素了。
	 * 没有的话则将该元素加入到map里,具体的实现思路如下
	 * @param numbers
	 * @param target
	 * @return
	 */
	public int[] twoSum(int[] numbers, int target) {  
        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();  
        int[] twoIndex = new int[2];      
        for(int i = 0; i < numbers.length; i++) {  
            if(map.containsKey(target - numbers[i])) {  
                twoIndex[1] = i + 1;  
                twoIndex[0] = map.get(target - numbers[i]) + 1;  
                return twoIndex;  
            }  
            map.put(numbers[i], i);  
        }  
          
        return null;  
    }
	/***
	 * 这里我们拓展一下,比如说一个数组里面有好多个组合相加都可以得到目标数,那么我们要找出所有的可能组合。这样其实我们也可以沿着上述的思路
	 * 就是在每次我们找到一对组合的情况下,将其记录下来,然后把满足组合的情况删除掉(如果不删除的话也可以,如果相同的数只能组合一次那么就删除,如果可以多次组合,那么就不删除),
	 * 再接着往后遍历,知道遍历完整个数组,实现如下
	 * @param numbers
	 * @param target
	 */
	public void AlltwoSums(int[] numbers, int target) {  
        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();  
        //int[] twoIndex = new int[2];      
        for(int i = 0; i < numbers.length; i++) {  
            if(map.containsKey(target - numbers[i])) {
            	node n = new node();
            	n.index2 = i+1;
            	n.index1 = map.get(target - numbers[i]) + 1;
            	nodeArr.add(n);
            	map.remove(target - numbers[i]);
            	map.remove(numbers[i]);
            }  
            map.put(numbers[i], i);  
        }  
    }  
	public static void main(String[] args) {
		int numbers[]={2,3,6,7,11,7,15};
		int target=9;
		twoSums t = new twoSums();
		int num[]=t.twoSum(numbers, target);
		System.out.println("只找出一组:");
		System.out.println(num[0]+" "+num[1]);
		System.out.println("找出所有的非可重复组合:");
		t.AlltwoSums(numbers, target);
		for (int i = 0; i < t.nodeArr.size(); i++) {
			System.out.println(t.nodeArr.get(i).index1 +" "+t.nodeArr.get(i).index2);
		}
		//要找出可以重复的所有组合的话那么就将如下两句注释掉
		//map.remove(target - numbers[i]);
    	//map.remove(numbers[i]);
		
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值