zoukankan      html  css  js  c++  java
  • 数组题解

    题目分类来源:https://leetcode-cn.com/circle/article/48kq9d/


    数组的遍历


    统计数组中的元素

    645

    697

    点击查看关于map的总结

    package Test;
    import java.util.*;
    public class Solution {
        //测试map的用法
        public static void test_Map() {
    
    /*        格式:
            Map.getOrDefault(key,默认值);
    
            Map中会存储一一对应的key和value。
            如果 在Map中存在key,则返回key所对应的的value。
            如果 在Map中不存在key,则返回默认值。*/
            Map<String,Integer>map=new HashMap<>();
            map.put("A", 11);
            map.put("B", 12);
            map.put("C",13);
            map.put("C",14);//更新了“C”对应的值
            Integer age=map.getOrDefault("C",30);
            System.out.println(age);
            age=map.getOrDefault("D",22);
            System.out.println(age);
            System.out.println(map.get("A"));//返回map中key对应的值
            System.out.println(map.get("E"));
            System.out.println(map.keySet());//返回map中所有key的列表
            for(String s:map.keySet()) {//迭代打印map中的key值
                System.out.println(s);
            }    
            System.out.println(map.values());//返回map中所有key对应的值列表
    /*结果
    14
    22
    11
    null
    [A, B, C]
    A
    B
    C
    [11, 12, 14]
    */
        }
        public static int findShortestSubArray(int[]nums) {
            if(nums==null|nums.length==0) return 0;
            if(nums.length==1) return 1;
            Map<Integer,Integer>l=new HashMap();//记录从左到右遍历数组每个元素第一次出现的位置
            Map<Integer,Integer>r=new HashMap();//记录从左到右遍历数组每个元素最后一次出现的位置
            Map<Integer,Integer>count=new HashMap();//记录元素和元素出现的次数,用来求“度”
            for(int i=0;i<nums.length;i++) {
                int x=nums[i];
                if(l.get(x)==null) l.put(x,i);
                r.put(x, i);
                count.put(x, count.getOrDefault(x, 0)+1);
            }
            int ans=nums.length;
            int degree=Collections.max(count.values());
            for(int x:count.keySet()) {
                if(degree==count.get(x)) {
                    ans=Math.min(ans, r.get(x)-l.get(x)+1);
                }
            }
            return ans;
        }
        
        public static void main(String[] args) {
            int[]nums= {1,2,2,3,1,4,2};
            System.out.println(findShortestSubArray(nums));
            //test_Map();
        }
    }
    View Code

    448

    找到所有数组中消失的数字

    给定一个范围在  1 ≤ a[i] ≤ nn = 数组大小 ) 的 整型数组,数组中的元素一些出现了两次,另一些只出现一次。

    找到所有在 [1, n] 范围之间没有出现在数组中的数字。

    您能在不使用额外空间且时间复杂度为O(n)的情况下完成这个任务吗? 你可以假定返回的数组不算在额外空间内。

    示例:

    输入:
    [4,3,2,7,8,2,3,1]
    
    输出:
    [5,6]
    

    step1.暴力遍历 时间复杂度O(n**2)  空间复杂度O(1)

     对于[1,n]中的每一个数字,在目标数组中去找,如果没有找到就把它记录在list中,如果有则跳过。

    static List<Integer> findDisappearedNumbers(int[] nums) {
            List<Integer>list=new ArrayList<>();
            for(int i=1;i<=nums.length+1;i++) {
                int flag=0;//假设当前数字没有出现在数组中
                for(int j=0;j<nums.length;j++) {
                    if(i==nums[j]) {
                        flag=1;
                        break;
                    }
                }
                if(flag==0) list.add(i);//如果没有出现就把这个数字存进list中
            }
            System.out.println(list.toString());
            return list;
        }
    View Code

    step2.使用额外空间 时间复杂度O(n)  空间复杂度O(n)

    使用一个数组counter记录nums中每个元素出现的次数,再遍历数组counter找到所有元素值是0的元素的下标即可.

    package Test;
    import java.util.*;
    public class Solution {
        static List<Integer> findDisappearedNumbers(int[] nums) {
            List<Integer>list=new ArrayList<>();
            int[]counter=new int[nums.length+1];//使用额外空间
            for(int i=0;i<nums.length;i++) {//记录nums中每个元素出现的次数
                counter[nums[i]]++;
            }
            for(int i=1;i<counter.length;i++) {
                if(counter[i]==0)
                    list.add(i);
            }
            System.out.println(list.toString());
            return list;
        }
        
        public static void main(String[] args) {
            int[]nums= {4,3,2,7,8,2,3,1};
            findDisappearedNumbers(nums);
            
        }
    }
    View Code

    step3.替换法

    一般的替换步骤如下:
        //首先,题目就是要对比一个排序号的顺序序列,查看哪些没出现,所以直接将两个数组摆出来:
        //4,3,2,7,8,2,3,1  数组1
        //1,2,3,4,5,6,7,8  数组2
        //上面是原数组,下面是序列数组;
        //遇到上面的数字,就将数组2中同样数字给替换为:替换字符(随便设置,这里可以设为*),意思就是该数字已经出现过了;
        //这样不断对照查找哪些元素出现过;则没被替换的就是没出现过的;
        //这基本是最基本的逻辑;

        //4,3,2,7,8,2,3,1
        //依次类推替换
        //1,2,3,*,5,6,7,8
        //1,2,*,*,5,6,7,8
        //1,*,*,*,5,6,7,8
        //1,*,*,*,5,6,*,8
        //1,*,*,*,5,6,*,*
        //1,*,*,*,5,6,*,*  位置2已经替换过,不用再替换;
        //1,*,*,*,5,6,*,*  位置3已经替换过,不用再替换;
        //*,*,*,*,5,6,*,*  此时5,6没被替换,说明5,6在数组1中没出现过;
        //但这样的替换需要额外用一个序列数组(1到n),
        //所以才有用自身数组元素的负数作为替换字符的方法,这样被替换字符也可以继续作为索引值使用;节省了一个数组空间;

    思路:将所有正数作为数组下标,置对应数组值为负值。那么,仍为正数的位置即为(未出现过)消失的数字。

    举个例子:
        原始数组:[4,3,2,7,8,2,3,1]
        重置后为:[-4,-3,-2,-7,8,2,-3,-1]
        [8,2] 分别对应的index为[5,6](消失的数字)

    class Solution {
        public List<Integer> findDisappearedNumbers(int[] nums) {
            List<Integer>r=new ArrayList<>();
            for(int i=0;i<nums.length;i++){
                if(nums[Math.abs(nums[i]) - 1]>0){
                    nums[Math.abs(nums[i])-1]=-nums[Math.abs(nums[i])-1];
                }
            }
            for(int i=0;i<nums.length;i++){
                if(nums[i]>0){
                    r.add(i+1);
                }
            }
            return r;
        }
    }
    View Code

    442

    思路:    找到数字i时,将位置i-1处的数字翻转为负数。 如果位置i-1 上的数字已经为负,则i是出现两次的数字。

    package Test;
    import java.util.*;
    public class Solution {
        
        public static List<Integer>findDuplicates(int[] nums){
            List<Integer>r=new ArrayList<>();
            for(int i=0;i<nums.length;i++) {
                int index=Math.abs(nums[i])-1;
                if(nums[index]<0) {
                    r.add(Math.abs(index+1));
                }
                if(nums[index]>0) {
                    nums[index]=-nums[index];
                }
            }
            return r;
        }
        
        public static void main(String[] args) {
            int[]nums= {4,3,2,7,8,2,3,1};
            List<Integer>list=findDuplicates(nums);
            System.out.println(list.toString());
        }
    }
    View Code

    41

    package Test;
    import java.util.*;
    public class Solution {
        //method1 首先最容易想到的就是暴力求解,从1开始一个个查找,没找到就直接返回
    /*    复杂度分析:
        时间复杂度:O(N*N)
              空间复杂度:O(1)
    */    
        public static int findMissingPositive0(int[]nums) {
            System.out.println(Arrays.toString(nums));
            for(int i=1;i<nums.length+1;i++) {
                int flag=0;//flag==0表示假设当前这个数没有出现
                for(int j=0;j<nums.length;j++) {
                    if(nums[j]==i) {
                        flag=1;
                        break;
                    }
                }
                if(flag==0) return i;
            }
            return nums.length+1;
        }
        
        //method2 先排序,再二分查找
    /*    复杂度分析:
        时间复杂度:O(N*log(N)。时间复杂度主要消耗在排序上,排序使用 O(N*log⁡N)。二分查找使用每一步使用的时间复杂度是 O(log⁡N),整体上仍然是 O(Nlog⁡N)
              空间复杂度:O(1)
    */
        public static int BS(int[]nums,int t) {
            int l=0,r=nums.length-1;
            while(l<=r) {
                int mid=l+(r-l)/2;
                if(nums[mid]==t) return mid;
                else if(nums[mid]<t)
                    l=mid+1;
                else r=mid-1;
            }
            return -1;
        }
        public static int findMissingPositive1(int[] nums){
            int len=nums.length;
            Arrays.sort(nums);
            System.out.println(Arrays.toString(nums));
            for(int i=1;i<len+1;i++) {
                int res=BS(nums,i);
                if(res==-1) return i;
            }
            return len+1;
        }
        //method3 把原数组的值全部存放到集合set中,然后再从1开始循环,判断这个数是否存在集合中,如果不存在直接返回
    /*    复杂度分析:
        时间复杂度:O(N),这里 N 表示数组的长度。第 1 次遍历了数组,第 2 次遍历了区间 [1, len] 里的元素。
              空间复杂度:O(N),把 N 个数存在哈希表里面,使用了 N个空间。
    */
        public static int findMissingPositive2(int[] nums) {
            Set<Integer>hashset=new HashSet<>();
            for(int num:nums) {
                hashset.add(num);
            }
            for(int i=1;i<nums.length;i++) {
                if(!hashset.contains(i))
                    return i;
            }
            return nums.length+1;
        }
        //method4 把数组元素存在对应的位置上(将数组视为哈希表)
    /*    那就是数值为 i 的数映射到下标为 i - 1 的位置.比如1存放到数组的第一个位置,3存放到数组的第3个位置.
        遍历一次数组把大于等于1的和小于数组大小的值放到原数组对应位置
        然后再遍历一次数组查当前下标是否和值对应,如果不对应那这个下标就是答案
                                             否则遍历完都没出现那么答案就是数组长度加1。
    */
    /*    复杂度分析:
        时间复杂度:O(N),这里 N 表示数组的长度。
              空间复杂度:O(1)
    */
        public static void swap(int[]A,int i,int j) {
            if(i!=j) {
                int tmp=A[i];A[i]=A[j];A[j]=tmp;
            }
        }
        public static int findMissingPositive3(int nums[]) {
            for (int i = 0; i < nums.length; i++) {
                //如果在指定的位置就不需要修改
                if (i + 1 == nums[i])
                    continue;
                int x = nums[i];
                if (x >= 1 && x <= nums.length && x != nums[x - 1]) {
                    swap(nums, i, x - 1);
                    i--;//抵消上面的i++,如果交换之后就不++;
                }
            }
            //最后在执行一遍循环,查看对应位置的元素是否正确,如果不正确直接返回
            for (int i = 0; i < nums.length; i++) {
                if (i + 1 != nums[i])
                    return i + 1;
            }
            return nums.length + 1;     //都正确则返回数组长度 + 1
        }
        public static void main(String[] args) {
            int[]nums= {7,8,9,11,12,4};
    //        System.out.println(findMissingPositive0(nums));
    //        System.out.println(findMissingPositive1(nums));
    //        System.out.println(findMissingPositive2(nums));
            System.out.println(findMissingPositive3(nums));
        }
    }
    View Code

    274

     453

    665

    package Test;
    import java.util.*;
    public class Solution {
        public static int[] twoSum1(int[] nums, int target) {
            for(int i=0;i<nums.length;i++) {
                for(int j=i+1;j<nums.length;j++) {
                    if(target-nums[j]==nums[i]) {
                        return new int[] {i,j};
                    }
                }
            }
            return new int[] {};
    
        }
        public static int[] twoSum2(int[] nums, int target) {
            Map<Integer,Integer>map=new HashMap<>();
            for(int i=0;i<nums.length;i++) {
                map.put(nums[i], i);
            }
            for(int i=0;i<nums.length;i++) {
                int r=target-nums[i];
                if(map.containsKey(r)&&map.get(r)!=i) {
                    return new int[] {i,map.get(r)};
                }
            }
            return new int[] {};
        }
        public static int[] twoSum3(int[] nums, int target) {
            Map<Integer,Integer>map=new HashMap<>();
            for(int i=0;i<nums.length;i++) {
                int r=target-nums[i];
                if(map.containsKey(r)) {
                    return new int[] {map.get(r),i};
                }
                map.put(nums[i],i);
            }
            return new int[]{};
        }
        public static void main(String[] args) {
            int[]nums= {2,7,11,15};
            int target=9;
            System.out.println(Arrays.toString(twoSum3(nums,target)));
            
        }
    }
    View Code

     118

    package Test;
    import java.util.*;
    public class Solution {
        public static List<List<Integer>> generate(int n) {
            List<List<Integer>>list=new ArrayList<List<Integer>>();
            if(n==0) return list;
            int [][]array=new int[n][n];
            
            for(int i=0;i<n;i++) {
                List<Integer>tmp=new ArrayList<>();
                for(int j=0;j<=i;j++) {
                    if(j==0||j==i) {
                        array[i][j]=1;
                    }else if(i>=1) {
                        array[i][j]=array[i-1][j]+array[i-1][j-1];
                    }
                    tmp.add(array[i][j]);
                }
                list.add(tmp);
            }
            return list;
        }
        public static void main(String[] args) {
            int n=5;
            for(List<Integer>list:generate(n)) {
                System.out.println(list);
            }
            
            
        }
    }
    View Code

    661

    1.递推法
    求出全部的值放在列表里,查找即可
    2.公式法
    如果输入的行数是n,那么该行内容依次是:1、(n-1)/1、(n-1)(n-2)/2、(n-1)(n-2)(n-3)/3...

    class Solution {
        public List<Integer> getRow(int rowIndex) {
                List<Integer> pre = new ArrayList<>();
                List<Integer> cur = new ArrayList<>();
                for (int i = 0; i <= rowIndex; i++) {
                    cur = new ArrayList<>();
                    for (int j = 0; j <= i; j++) {
                        if (j == 0 || j == i) {
                            cur.add(1);
                        } else {
                            cur.add(pre.get(j - 1) + pre.get(j));
                        } 
                    }
                    pre = cur;
                }
            return cur;
        }
    }
    View Code
  • 相关阅读:
    1. Ubuntu下使用pip方式安装tensorflow
    CSS 属性
    django运行django-admin.py无法创建网站
    jQuery各种效果举例
    一生莫轻舞,一舞一生苦
    即使你美丽动人,也要具备更华丽的着装
    即使有一颗强大的心,也要让人看到你美丽的外表
    python操作RabbiMQ
    windows下python安装paramiko
    python用paramiko将执行的结果存入excel表格
  • 原文地址:https://www.cnblogs.com/xuechengmeigui/p/13602298.html
Copyright © 2011-2022 走看看