zoukankan      html  css  js  c++  java
  • 编程题:两数之和&数组中相加为0的三元数组

    两数之和

    给出一个整数数组,请在数组中找出两个加起来等于目标值的数,
    你给出的函数twoSum 需要返回这两个数字的下标(index1,index2),需要满足 index1 小于index2.。注意:下标是从1开始的
    假设给出的数组中只存在唯一解
    例如:

    给出的数组为 {20, 70, 110, 150},目标值为90
    输出 index1=1, index2=2

    数组中相加为0的三元数组

    给出一个有n个元素的数组S,S中是否有元素a,b,c满足a+b+c=0?找出数组S中所有满足条件的三元组。
    注意:
    1. 三元组(a、b、c)中的元素必须按非降序排列。(即a≤b≤c)
    2. 解集中不能包含重复的三元组。
    例如,给定的数组 S = {-10 0 10 20 -10 -40},解集为(-10, 0, 10) (-10, -10, 20)

    思路

      之所以将两道题目放在一起讲,主要时因为当初这两道题给了我很强的既视感,两个题目解题思路相互影响,导致了我走向了两个错误的方向,每一道题都走错了。

      两数之和:第一反应是排序遍历,因为求和排序后会方便遍历,然而该题目需要返回的是下标,排序打乱顺序会影响结果,如果强行实现也会多出许多用来记录原位置的开销。那么放弃了排序的算法,使用map以记录(数值,下标),每次遍历前判断是否存在target-当前值的值在map中,有则取出并返回下标。

      数组中相加为0的三元组:做到这个题的时候刚做完两数之和,脑子一下子没转过来,a+b+c=0不就是a+b=-c吗?然而这个题目不是唯一解,而且需要返回对的是三元组按非降序排列,而且不允许重复。所以排序后再遍历是一个很好的方法。

    解题:两数之和

    /**
         *
         * @param numbers int整型一维数组
         * @param target int整型
         * @return int整型一维数组
         */
        public int[] twoSum (int[] numbers, int target) {
            /*从数组中返回和是targe的两个数的下标,假设有值且唯一,下标从1起算*/
            Map<Integer,Integer> map= new HashMap<>();
            //PrintIntArray(numbers);
            for(int i=0;i<numbers.length;i++){
                if(map.containsKey(target-numbers[i])){
                    return new int[]{map.get(target-numbers[i])+1,i+1};
                }
                map.put(numbers[i],i);
            }
            return new int[]{-1,-1};
        }

    解题:数组中相加为0的三元数组

        public ArrayList<ArrayList<Integer>> threeSum(int[] num) {
           ArrayList<ArrayList<Integer>> res = new ArrayList<>();
           /*先排序*/
            sort(num);
            for(int i=0;i<num.length;){
                if(num[i]>0) break; //优化
                for(int j=i+1;j<num.length;){
                    if(num[i]+num[j]>0) break;
                    for(int k=j+1;k<num.length;){
                        if(num[i]+num[j]+num[k]>0){
                            break; //优化
                        }
                        if(num[i]+num[j]+num[k]==0){
                            ArrayList<Integer> alist = new ArrayList<>();
                            alist.add(num[i]);
                            alist.add(num[j]);
                            alist.add(num[k]);
                            res.add(alist);
                            break;
                        }
                        int temp = num[k];
                        while (k<num.length&&num[k]==temp){//跳过重复项
                            k++;
                        }
                    }
                    int temp = num[j];
                    while (j<num.length&&num[j]==temp){//跳过重复项
                        j++;
                    }
                }
                int temp = num[i];
                while (i<num.length&&num[i]==temp){//跳过重复项
                    i++;
                }
            }
           return res;
    
        }
    当你深入了解,你就会发现世界如此广袤,而你对世界的了解则是如此浅薄,请永远保持谦卑的态度。
  • 相关阅读:
    用Fiddle跟踪调试移动表单
    查找指定表、字段上面的默认值约束
    sql跳过非工作日(周末和节假日)
    python学习(一)
    charles抓包
    jemeter简单压测
    jemeter接口测试
    postman接口测试
    接口测试基础知识学习
    定期小结
  • 原文地址:https://www.cnblogs.com/liwxmyself/p/14699245.html
Copyright © 2011-2022 走看看