zoukankan      html  css  js  c++  java
  • [leetcode]1-Two Sum

    1. Two Sum

    Given an array of integers, return indices of the two numbers such that they add up to a specific target.
    
    You may assume that each input would have exactly one solution, and you may not use the same element twice.
    
    Example:
    Given nums = [2, 7, 11, 15], target = 9,
    
    Because nums[0] + nums[1] = 2 + 7 = 9,
    return [0, 1].
    

    我的代码

     public int[] twoSum(int[] nums, int target) {
            //找出最值确定堆大小
            int min = nums[0], max = nums[0];
            for (int i = 0; i < nums.length; i++) {
                if (nums[i] > max) {
                    max = nums[i];
                } else if (nums[i] < min) {
                    min = nums[i];
                }
            }
    
            String heap[] = new String[max - min + 1];
            for (int i = 0; i < heap.length; i++) {
                heap[i] = "";
            }
            //遍历nums , 初始化堆 存放nums下标i
            for (int i = 0; i < nums.length; i++) {
                if (heap[nums[i] - min] == "") {
                    heap[nums[i] - min] = "" + i;
                } else {
                    heap[nums[i] - min] = heap[nums[i] - min] + "," + i;
                }
            }
    
            int result[] = new int[2];
            //遍历堆
            for (int i = 0; i < heap.length; i++) {
                if (heap[i] != "" && (target - i - 2 * min) < heap.length && heap[target - i - 2 * min] != "") {
                    if (heap[i].contains(",")) {
                        String[] split = heap[i].split(",");
                        result[0] = Integer.valueOf(split[0]).intValue();
                        result[1] = Integer.valueOf(split[1]).intValue();
                        break;
    
                    } else {
                        result[0] = Integer.valueOf(heap[i]).intValue();
                        result[1] = Integer.valueOf(heap[target - i - 2 * min]).intValue();
                        break;
                    }
                }
            }
            return result;
        }
    

    思路:

    初始化一个堆,比如数组a【1,2,7,11】找9, 那么会初始化一个11长度的数组b,对于输入数组12711, 标记 b对应下标为127 11的值分别为0,1,2,3(即在a数组中的下标)。 然后遍历b, 只要一个数和他相对于9的差数都被标记过,比如2,7直接返回两个下标即可。
    调试过程中发现了重数{3,3},负数等情况, 做了一些调整。
    复杂度: 时间O(n) 空间O(n)

    结果:

    9ms 优于75% (cn站成绩是8ms,优于92% 说明总站可能样本什么更全一些,故以后都在总站提交)

    调优:

    2:Two-pass Hash Table

    二次循环hash表,解决暴力方法中过多遍历的问题,并且节省大量空间。
    第一遍初始化hash表,
    第二遍匹配。

    3:One-pass Hash Table

    通过2,可以看见可以同时初始化与匹配,匹配中即返回,否则继续初始化。
    一次遍历即可。

    2.3的代码见官网https://leetcode.com/problems/two-sum/solution/

    超级调优?

    3理论上已经是最优的了,耗时6ms,但是我发现官网竟然还有更吊的

    
    class Solution {
        public int[] twoSum(int[] nums, int target) {
           int t=4096;
    		int bitMode=t-1;
            int[] temp=new int[t];
            int length=nums.length;
            int firstValue=nums[0];
    
            for(int i=1;i<length;i++){
                int different=target-nums[i];
                int current=nums[i];
                if(different==firstValue) {
                	return new int[] {0,i};
                }
                int differentIndex=temp[different&bitMode];
                if(differentIndex!=0){
                    return new int[] {differentIndex,i};
                }
    
                int currentIndex=current&bitMode;
                temp[currentIndex]=i;
            }
            return null;
        }
    }
    

    这个使用了位与来模拟,
    但是我使用该数据测试,发现该解法是错的。
    int nums[] = {-1,0,1,2, 4097, 8193};
    int target = 8194;

  • 相关阅读:
    centos7 安装配置手册
    常用mysql统计信息(mysql5.6)
    yum将需要安装的软件依赖下载到本地
    impala使用指南
    redis集群配置
    VIM
    Vim自动补全插件----YouCompleteMe安装与配置
    vim中自动格式化代码
    vscode_插件_shell格式化工具安装
    Anaconda+vscode 搭建开发环境
  • 原文地址:https://www.cnblogs.com/novaCN/p/8747126.html
Copyright © 2011-2022 走看看