• (hash map)Two Sum, sorted(排序+双指针)closest,小于或大于的对数,组成不同的对数


    原版 sorted

    [抄题]:

    [思维问题]:

    存sum - nums[i](补集),若出现第二次则调出

    [一句话思路]:

    hashmap中,重要的数值当做key,角标当做value.

    [画图]:

    [一刷]:

    [总结]:

    [复杂度]:n/n

    [英文数据结构,为什么不用别的数据结构]:

    2根指针 n^2

    [其他解法]:2根指针 j=i + 1

    [题目变变变]:

    Subarray Sum Equals K map

    Two Sum IV - Input is a BST 

    class Solution {
        public int[] twoSum(int[] nums, int target) {
            int[] result = new int[2];
            HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
            
            for (int i = 0; i < nums.length; i++) {
                if (map.containsKey(target - nums[i])) {
                    result[0] = map.get(target - nums[i]);
                    result[1] = i;
                    
                    return result;
                }
                map.put(nums[i],i);
            }
            return result;
        }
    }
    View Code

    closest

    [抄题]:

    找到两个数字使得他们和最接近target

    [思维问题]:

    j = i + 1, 复杂度平方,不行

    [一句话思路]:

    排序后,两根指针都往中间走,能比较大小。降低复杂度。

    [画图]:

    [一刷]:

    1. corner case是数组长度不足2
    2. 每一块代码要分开

    [总结]:同样是两根指针,用排序可以降低遍历的复杂度

    [复杂度]:两根指针是n^2/1

    [英文数据结构,为什么不用别的数据结构:

    [其他解法]:

    [题目变变变]:(都用的排序)返回和小于等于、大于target的对数;3 sum closest

    /**
    * 本参考程序来自九章算法,由 @九章算法 提供。版权所有,转发请注明出处。
    * - 九章算法致力于帮助更多中国人找到好的工作,教师团队均来自硅谷和国内的一线大公司在职工程师。
    * - 现有的面试培训课程包括:九章算法班,系统设计班,算法强化班,Java入门与基础算法班,Android 项目实战班,
    * - Big Data 项目实战班,算法面试高频题班, 动态规划专题班
    * - 更多详情请见官方网站:http://www.jiuzhang.com/?source=code
    */ 
    
    public class Solution {
        /**
         * @param nums an integer array
         * @param target an integer
         * @return the difference between the sum and the target
         */
        public int twoSumClosest(int[] nums, int target) {
            if (nums == null || nums.length < 2) {
                return -1;
            }
            
            Arrays.sort(nums);
            
            int left = 0, right = nums.length - 1;
            int diff = Integer.MAX_VALUE;
            
            while (left < right) {
                if (nums[left] + nums[right] < target) {
                    diff = Math.min(diff, target - nums[left] - nums[right]);
                    left++;
                } else {
                    diff = Math.min(diff, nums[left] + nums[right] - target);
                    right--;
                }
            }
            
            return diff;
        }
    }
    View Code

     返回小于、大于的对数

    [抄题]:

    给定一个整数数组,找出这个数组中有多少对的和是小于或等于目标值。返回对数。

    [思维问题]:

    不理解cnt为什么是right - left,因为中间的数其实都可以。

    有数组先排序

    [一句话思路]:

    类似于closest,两边都往中间靠,调节sum的大小。

    [画图]:

    [一刷]:

    1. corner case表示不存在的对数时,返回0
    2. 一定要写排序,不排序啥都完了。类名是Arrays,不是Array。
    3. 之前的数组[2]是有上下限即可在循环中返回,此时cnt要累积才能返回。

    [总结]:

    用排序降低复杂度,两边往中间靠。

    [复杂度]:

    [英文数据结构,为什么不用别的数据结构]:

    [其他解法]:

    [题目变变变]:

    public Class Solution {
    
     public int twoSums5(int[] nums, int target) {
    
        if (nums.length < 2 || nums.length == null) {
            return 0;
        }
    
        int left = 0;
        int right = nums.length - 1;
        int cnt = 0;
    
        Arrays.sort(nums);//
        while(left < right) {
            int v = nums[left] + nums[right];
            if (v <= target) {
                left ++;
            }
            else {
                cnt += right - left;
                right —;
            }
        }
    
        return cnt;
    }
    }
    View Code

    组成不同的对数

    [抄题]:

    给一整数数组, 找到数组中有多少组 不同的元素对 有相同的和, 且和为给出的 target 值, 返回对数.

    [思维问题]:

    不知道左右两个指针移动多少。其实是切入点不对:直接从目标v = target切入,大了right--, 小了left++。

    corner case是连续的值都相等,nums[right] == nums[right + 1],没想到。

    [一句话思路]:

    [画图]:

    [一刷]:

    1. 是两边往中间靠,所以nums[right] == nums[right + 1]时,也是right--, 不是++。

    [总结]:

    closest,小于或大于的对数,组成不同的对数 都是排序+两根指针的做法

    [复杂度]:

    [英文数据结构,为什么不用别的数据结构]:

    [其他解法]:

    [题目变变变]:

    public class Solution {
     public int twoSum6(int nums[], int target) {
        if (nums.length < 2 || nums == null) {
            return 0;
        }
    
        Arrays.sort(nums);
        int left = 0;
        int right = nums.length - 1;
        int count = 0;
        int v = nums[left] + nums[right];
    
        while(left < right) {
            if (v == target) {
                left++;
                right—;
                count++;
            }
            while((left < right) && (nums[right] == nums[right + 1])) {
                right—;//
            }
            while((left < right) && (nums[left] == nums[left - 1])) {
                left++;
            }
        }
            else if(v > target) {
                right—;
            }
            else {
                left++;
            }
    
        return count;
    }
    }
    View Code
  • 相关阅读:
    python--tkinter桌面编程开发--记事本
    Python--面向对象编程
    Python--面向对象编程--时钟实例开发
    Python学习笔记--2--面向对象编程
    Python学习笔记--1
    epoll聊天室的实现
    操作系统--虚拟存储器
    操作系统--存储器管理
    操作系统--分页存储管理中逻辑地址转换为物理地址
    操作系统--处理机调度与死锁
  • 原文地址:https://www.cnblogs.com/immiao0319/p/8033539.html
Copyright © 2020-2023  润新知