• Coursera Algorithms week1 算法分析 练习测验: 3Sum in quadratic time


    题目要求:

    Design an algorithm for the 3-SUM problem that takes time proportional to n2 in the worst case. You may assume that you can sort the n integers in time proportional to n2 or better.

    分析:

    《算法4》这本书提供的TwoSumFast解法为NlogN,ThreeSumFast解法为N2logN,根据课后练习,要实现3Sum复杂度为N2,建议先把2Sum复杂度实现为N。同时教材提示用排好序的数组可以实现复杂度N。我想了很久,没有发现排好序的数组对复杂度降至N有太大帮助,于是在网上搜索了下大家的做法。网上的大部分都是建议用set或map来做,我决定采用map试试,果然用map很方便。代码如下:

     1 import java.util.Arrays;
     2 import java.util.HashMap;
     3 
     4 public class TwoSumLinear {
     5     public static int count(int[] a){
     6         int cnt = 0;
     7         int n = a.length;
     8         HashMap<Integer,Integer> map = new HashMap<Integer,Integer>();
     9         for(int i =0; i<n;i++){
    10             if(map.get(a[i]) == null) map.put(a[i], i);
    11             Integer negIndex = map.get(-a[i]);
    12             if(negIndex != null && negIndex != i){
    13                 System.out.println("a["+negIndex+"]="+(-a[i])+"和a["+i+"]="+a[i]);
    14                 cnt++;
    15             }
    16         }
    17         return cnt;
    18     }
    19     public static void main(String[] args){
    20         int[] a = { 30, -40, -20, -10, 40, 0, 10, 5 };
    21         System.out.println(Arrays.toString(a));
    22         System.out.println(count(a));
    23     }
    24 }

    3Sum的作业提示可以先将数组排序,基于这个思路,结合写过的2Sum线性实现方法,写出了复杂度为N2的3Sum,个人认为实现的方式已经很精简了。

     1 import java.util.Arrays;
     2 import java.util.HashMap;
     3 
     4 public class ThreeSumQuadratic {
     5     public static int count(int[] a, int target) {
     6         Arrays.sort(a);// 数组从小到大排序,后面要使用有序数组的性质简化运算
     7         System.out.println(Arrays.toString(a));
     8         System.out.println("target="+target);
     9         int cnt = 0;
    10         int n = a.length;
    11         HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
    12         for (int i = 0; i < n; i++) {
    13             map.put(a[i], i); //以数组value为key,index为map值
    14         }
    15         for (int i = 0; i < n - 1; i++) {//i不会超过n-2
    16             for (int j = i + 1; j < n; j++) {//j从i+1开始统计,不会超过n-1
    17                 int smallValue = a[i] + a[j]; //因为排好序了,所以最开始的a[i]+a[j]
    18                 if (smallValue > target) //当a[i]+a[j]>target时没必要计算了,因为后续的查找就会重复
    19                     break;
    20                 int bigValue = target-smallValue; //计算出对应的数值较大的value
    21                 Integer bigIndex = map.get(bigValue); //查找数值较大的value所在的位置
    22                 if (bigIndex != null && bigIndex > i && bigIndex > j) {
    23                     System.out.println(
    24                             "[" + i + "]=" + a[i] + ",[" + j + "]" + a[j] + ",[" + bigIndex + "]" + (bigValue));
    25                     cnt++;
    26                 }
    27             }
    28         }
    29         return cnt;
    30     }
    31 
    32     public static void main(String[] args) {
    33         int[] a = { 30, -40, -20, -10, 40, 0, 10, 5 };        
    34         System.out.println(count(a,0));
    35     }
    36 }
  • 相关阅读:
    Java 位运算(移位、位与、或、异或、非)
    解决Android Studio 2.2.3中添加.cpp .h文件在Project->Android无法显示,无法正常编译问题。
    [ACM] HDU 5083 Instruction (模拟)
    Vbox视图热键
    Android Drawable 与 LayerList综合汇总
    数学之路-python计算实战(14)-机器视觉-图像增强(直方图均衡化)
    HDU 2896 病毒侵袭 AC自己主动机题解
    对团队中“这是某某某的问题”引起的思考
    杭电 2201
    三层架构
  • 原文地址:https://www.cnblogs.com/evasean/p/7208900.html
Copyright © 2020-2023  润新知