3Sum Time Limit Exceeded HashMap 优化过程

  昨晚,在做leetcode上的3Sum题目时,感觉这道题目和2Sum很像,当时解决2Sum时,思路如下:

用HashMap的key存储 num[i],value存储下标 i,之后在遍历数组num时,判断target-num[i]是否在HashMap的key中,大致解题思路是这样的。于是我决定继续用这个思路解决3Sum问题。思路如下:

用2层for循环(同理4Sum问题用3层for循环),Java代码(此段代码Time Limit Exceeded)如下:

public List<List<Integer>> threeSum(int[] num) {

        Arrays.sort(num);
        List<List<Integer>> listAll = new ArrayList<List<Integer>>();
        Map<Integer, Integer> hm = new HashMap<Integer, Integer>();
        for(int i = 0; i < num.length; i++) {
            hm.put(num[i], i);
        }
        for (int i = 0; i < num.length; i++) {
            int oneTmp = -num[i];
            if (oneTmp < 0) {
                break;
            }
            for (int j = i + 1; j < num.length; j++) {
                int thirdTmp = oneTmp - num[j];
                if (hm.containsKey(thirdTmp) && hm.get(thirdTmp) > j) {
                    List<Integer> listTmp = new ArrayList<Integer>();
                    listTmp.add(num[i]);
                    listTmp.add(num[j]);
                    listTmp.add(thirdTmp);
                    if (!listAll.contains(listTmp)) {
                        listAll.add(listTmp);
                    }
                }
            }
        }
        return listAll;
    }

上面的这段代码提交时,一直显示Time Limit Exceeded。经过检查,发现问题出现在上面的红色代码处,我是计算了很多重复的triplet后,然后再用listAll的contains判断并去重,这样的操作会占用一定的时间,导致Time Limit Exceeded。

第一次优化:优化第二层for循环的下标j的遍历方法,Java代码(很奇怪的是这段代码第一次提交时Accepted了,之后几次提交都是Time Limit Exceeded)如下:

public List<List<Integer>> threeSum(int[] num) {

        Arrays.sort(num);
        List<List<Integer>> listAll = new ArrayList<List<Integer>>();
        Map<Integer, Integer> hm = new HashMap<Integer, Integer>();
        for(int i = 0; i < num.length; i++) {
            hm.put(num[i], i);
        }
        for (int i = 0; i < num.length; i++) {
            int oneTmp = -num[i];
            if (oneTmp < 0) {
                break;
            }
            for (int j = i + 1; j < num.length; j++) {
                int thirdTmp = oneTmp - num[j];
                if (hm.containsKey(thirdTmp) && hm.get(thirdTmp) > j) {
                    List<Integer> listTmp = new ArrayList<Integer>();
                    listTmp.add(num[i]);
                    listTmp.add(num[j]);
                    listTmp.add(thirdTmp);

                    listAll.add(listTmp);
                    while ((j < num.length - 1) && (num[j] == num[j + 1])) {
                        j ++;
                    }
                }
            }
        }
        return listAll;
    }

其实就是把第一段代码中的红色部分,替换成黄色部分。

第二次优化,就是优化第一层for循环的下标 i 的遍历方法,最终Java代码(这次以318ms Accepted了)如下:

public List<List<Integer>> threeSum(int[] num) {

        Arrays.sort(num);
        List<List<Integer>> listAll = new ArrayList<List<Integer>>();
        Map<Integer, Integer> hm = new HashMap<Integer, Integer>();
        for(int i = 0; i < num.length; i++) {
            hm.put(num[i], i);
        }
        for (int i = 0; i < num.length; i++) {
            int oneTmp = -num[i];
            if (oneTmp < 0) {
                break;
            }
            for (int j = i + 1; j < num.length; j++) {
                int thirdTmp = oneTmp - num[j];
                if (hm.containsKey(thirdTmp) && hm.get(thirdTmp) > j) {
                    List<Integer> listTmp = new ArrayList<Integer>();
                    listTmp.add(num[i]);
                    listTmp.add(num[j]);
                    listTmp.add(thirdTmp);
                    listAll.add(listTmp);
                    while ((j < num.length - 1) && (num[j] == num[j + 1])) {
                        j ++;
                    }
                }
            }
            while ((i < num.length - 1) && (num[i] == num[i + 1])) {
                i ++;
            }
        }
        return listAll;
    }

其实就是在第二段代码的基础上,再加上面绿色代码。至此,基于HashMap的解决3Sum问题的Java代码优化结束~

时间: 2024-09-23 02:31:54

3Sum Time Limit Exceeded HashMap 优化过程的相关文章

某系统单点登录性能测试诊断分析优化过程

某系统单点登录性能测试诊断分析优化过程 原因说明 下面描述的是前段时间协助本地一家上市IT公司做产品技术选型时对他们的技术框架进行性能测试与优化过程记录,因测试过程中涉及数据库选型和各类问题的监控分析优化,篇幅比较大,本次主要是描述在同样基础软硬件下.同样应用工程包和框架.同样数据量下,针对MYSQL环境下进行单点登录压力测试的结果过程记录. 初始环境配置 测试内容 1.            用户登录,首页查看,退出 2.  某业务交易新增.查询.删除.上传文件 3.  业务审批流程创建.提交

JVM运行报错:GC overhead limit exceeded

今天在折腾OOM和java的4种引用类型的时候,在运行过程中JVM报了一个错误: java.lang.OutOfMemoryError: GC overhead limit exceeded 这个错误平时遇到的概率很少很少,今天无意中遇到了,这里做个记录.oracle/sun官网的解释是: The concurrent collector will throw an OutOfMemoryError if too much time is being spent in garbage colle

【夯实Mysql基础】记一次mysql语句的优化过程!

1. [事件起因] 今天在做项目的时候,发现提供给客户端的接口时间很慢,达到了2秒多,我第一时间,抓了接口,看了运行的sql,发现就是 2个sql慢,分别占了1秒多. 一个sql是 链接了5个表同时使用了 2个 order by和 1个limit的分页 sql. 一个sql是上一个sql的count(*),即链接了5个表,当然没有limit了(取总数). 2. [着手优化] 1)[优化思路] 第一条是 做client调用 service层的数据缓存 第二条就是 优化sql本身. 这里着重讲一下

Spark 1.4.1中Beeline使用的gc overhead limit exceeded

最近使用SparkSQL做数据的打平操作,就是把多个表的数据经过关联操作导入到一个表中,这样数据查询的过程中就不需要在多个表中查询了,在数据量大的情况下,这样大大提高了查询效率. 我启动了thriftserver,然后通过beeline去连接thriftserver, 打平操作进行的很顺利,但是在执行groupby操作的时候beeline报了一个错误:gc overhead limit exceeded 我分析可能是thriftserver报的错误.但是查看了thriftserver的日志没有任

spark-OutOfMemory:GC overhead limit exceeded 解决

今天准备跑自己的spark程序,但是运行过程中遇到了OutOfMemory:GC overhead limit exceeded的错误. 原以为是数据集太大,google了一番,以为是内存不够了,但是在webui一看其实数据集好像也不是很大,但是还是尝试提高了内存配置,通过提高spark.executor.memory和spark.shuffle.memoryFraction,降低spark.storage.memoryFraction,来提高机器可用的堆空间. 再次运行发现,问题依旧.在苦恼中

Spark OOM:java heap space,OOM:GC overhead limit exceeded解决方法

问题描述: 在使用spark过程中,有时会因为数据增大,而出现下面两种错误: java.lang.OutOfMemoryError: Java heap space java.lang.OutOfMemoryError:GC overhead limit exceeded 这两种错误之前我一直认为是executor的内存给的不够,但是仔细分析发现其实并不是executor内存给的不足,而是driver的内存给的不足.在standalone client模式下用spark-submit提交任务时(

Conversion to Dalvik format failed: Unable to execute dex: GC overhead limit exceeded异常解决

在运行工程的时候,Eclipse长时间停留在100%那个进度. 最后报错 Unable to execute dex: GC overhead limit exceeded Conversion to Dalvik format failed: Unable to execute dex: GC overhead limit exceeded 解决方案: 设置Xms为512 和1024  在eclipse的目录下的eclipse.ini文件中改 openFile --launcher.XXMax

Time Limit Exceeded的原因及避免方法

经常会遇到这种令人抓狂的情况 自己编写的程序在codeblocks上怎么编译运行都能输出正确结果 然而一提交,却无法Accept,很多时候显示的并不是Wrong Answer 而是比WrongAnswer更令人绝望的  . 在oj中,给定的Time Limit 是1000MS,出现Time Limit  Exceeded则说明这个程序的运行时间超过了这个限度. 经过几道题,我猜想了几个关于超时的原因: ———————————————————————————————————————————————

java.lang.OutOfMemoryError GC overhead limit exceeded原因分析及解决方案

最近一个上线运行良好的项目出现用户无法登录或者执行某个操作时,有卡顿现象.查看了日志,出现了大量的java.lang.OutOfMemoryError: GC overhead limit exceeded错误. oracle官方给出了这个错误产生的原因和解决方法: Exception in thread thread_name: java.lang.OutOfMemoryError: GC Overhead limit exceeded Cause: The detail message "G