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

解法一:暴力破解(穷举法,不提倡)
(穷举,时间复杂度:O(n^2),正常是不会用这个滴,假如只是为了快速解题,对时间没有限制,用这个最简单)

//暴力枚举法
function getSum1(arr,sum) {

  //去掉数组中的重复元素
  var items = new Set(arr);
  arr = Array.from(items);
  console.log(arr)

   for(var i=0;i<arr.length;i++)
      for(var j=i+1;j<arr.length;j++){
        if(arr[i]+arr[j]===sum){
          console.log(arr[i]+"+"+arr[j]);
        }
  }
}
var arr =[2,1,8,-2,-7,-1,-2,-8];
getSum1(arr,0);

解法二:二分法(相当于用两个指针)
两个指针二分查找
(排序时间复杂度为O(nlog(n)),while最多O(N),所以最终程序的时间复杂度为:O(nlo(n)))

//排序二分查找法
function getSum2(arr,sum) {
  //数组排序
  arr.sort(function (a,b) {
    return a-b;//必须指定排序函数,否则按照字符升序排序
  });

  //去掉数组中的重复元素
  var items = new Set(arr);
  var arr2 = Array.from(items);
  console.log(arr2);

  var left=0,right =arr2.length-1;
  while(left<right){
    if(arr2[left]+arr2[right]>sum){
      right--;
    }else if(arr2[left]+arr2[right]<sum){
      left++;
    }else if(arr2[left]+arr2[right]==sum){
      console.log(arr2[left]+" + "+arr2[right]+"="+sum);//常犯错误,将变量名写错,arr2写成arr

      left++;
      right--;
    }
  }
}
//getSum2(arr,0);

关键点:1.数组排序,2.去重,3.2分查找

扩展为3个元素

参考:http://blog.csdn.net/tonghuawanli/article/details/61196462
http://blog.csdn.net/vvaaiinn/article/details/45220443

public static ArrayList<ArrayList<Integer>> threeSum(int[] num)  
    {  
        ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();  
        if(num == null||num.length<3)//如果只有2个数字 或者为空 返回空  
            return res;  
        Arrays.sort(num);  
        for(int i = 0; i<num.length -2;i++)// 保证最后得有num.length-1 和num.length-2两个数,才可以进循环  
        {  
            if(i > 0 && num[i] == num[i-1])//如果要是有重复的直接跳过。  
                continue;  
            ArrayList<ArrayList<Integer>> cur = twoSum(num,i+1,-num[i]); //得到当前数字可以组合出来的数字序列的子集。  
            res.addAll(cur);  
        }  

        return res;          
    }  
    public static ArrayList<ArrayList<Integer>>twoSum (int []num,int start,int target)  
    {  

        ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();   
        if(num == null||num.length < 2)  
            return res;  
        int l = start;//起始位置  
        int pri = start-1;//当前数字  
        int r = num.length-1;//终止位置  
        while(l < r)//采用夹逼,逼近target  
        {  
            if(num[l]+num[r] == target)//  
            {  
                ArrayList<Integer> te = new ArrayList<Integer>();//符合的话 把三个数放入到list中  
                te.add(num[pri]);  
                te.add(num[l]);  
                te.add(num[r]);  
                res.add(te);  
                int k = l + 1;//从l的下一个开始 去除重复。  
                while(k < r&& num[k] == num[l])  
                    k++;  
                l = k;  
                k = r - 1;//去除R的重复  
                while(k > l &&num[k] == num[r])  
                    k--;  
                r = k;  
            }  
            else if(num[l] + num[r] > target)//夹逼  
                r--;  
            else l++;         
        }  

        return res;  

    } 

两个元素求和:

参考(java版): http://blog.csdn.net/qyys20/article/details/53349558

两种方法(1.二分查找;2.hash表;两种方法时间复杂度都为O(n),但第一种空间复杂度为O(1),第二种为O(n)) http://www.cnblogs.com/hapjin/p/5746659.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值