0
点赞
收藏
分享

微信扫一扫

初级算法(一)

zhyuzh3d 2022-03-21 阅读 92

初级算法(一)

1、引言

2、数组中是否有重复元素

​ 最先想到是一个暴力解决,就是两层for循环,虽然能解出来,但是力扣上可能会超出时间限制。所以这个解决办法并不是最优解。

  //方法一:暴力解决,执行用时750ms,内存消耗:55.3MB,力扣上有可能会显示超出时间限制
    public boolean containsDuplicate(int[] nums){
        if(nums.length<=1)
            return false;
        for (int i = 0; i <nums.length ; i++) {
            for (int j = i+1; j <nums.length ; j++) {
                if(nums[i]==nums[j])
                    return true;
            }
        }
        return false;
    }

​ 其次,可以对数组进行排序。用一个指针加循环的方式。排序后的数组,如果里面有元素重复那肯定都是相邻的。

//方法二:先排序,再进行对比。执行用时:22ms 内存消耗:55.1MB
    public boolean containsDuplicate2(int[] nums){
        if(nums.length<=1)
            return false;
        int a=0;
        Arrays.sort(nums);
        for (int i = 1; i <nums.length ; i++) {
            if(nums[a]==nums[i]){
               return true;
            }else{
                a++;
            }
        }
        return false;
    }

​ 第三种方法是采用Java带的数据结构,set集合。因为set集合存储的都是不允许有重复的元素,set中的add方法,如果添加的是集合里已有的元素,则返回值就是false。

//方法三:使用数据结构中的set集合,set集合中不允许有重复的元素,进行重复元素添加的时候,
    // set会覆盖其中的值,并返回一个false
    //力扣执行时间:4ms,内存消耗:49.2MB
    public boolean containsDuplicate3(int[] nums){
        if(nums.length<=1)
            return false;
        Set<Integer> set=new HashSet<Integer>();
        for (int num:nums){
            if(!set.add(num)){
                return true;
            }
        }
        return false;
    }

3、数组中只出现一次的数字

​ 这里可以先对数组进行排序,因为重复的元素一定是相隔一起的。

//方法一:先对数组进行排序,然后挑出只出现一次的元素
    //执行用时:5ms  内存消耗:41.5MB
    public int singleNumber(int[] nums) {
        if(nums.length<=1)
            return nums[0];
        Arrays.sort(nums);
        int a=0;
        for (int i = 1; i <nums.length ; i+=2) {
            if(nums[a]==nums[i]){
                a+=2;
            }else{
                return nums[a];
            }
        }
        return nums[nums.length-1] ;
    }

​ 方法二就是利用Java语言中的set集合的特性。利用set集合存储只出现一次的数字。

//方法二:还是使用的set集合的特性,就是不可重复和无序
    //执行用时:10ms ,内存消耗:41.8M
    public int singleNumber2(int[] nums) {
        if(nums.length<=1){
            return nums[0];
        }
        Set<Integer> set=new HashSet<Integer>();
        for(int num : nums){
            if(!set.add(num)){
                set.remove(num);
            }
        }
        return (int)set.toArray()[0];
    }

​ 方法三则是这个问题的最优解,因为力扣的题目要求上,明确说明了数组的元素就算重复,也只会重复两次。所以可以采用异或运算的方法。

//方法三:异或运算做优解,因为数组里的数最多重复一次
    //执行时间:1ms,内存消耗:41.4MB
    //异或运算的规律:自己和自己异或等于0,不同的异或结果为1并且异或运算具有交换律
    public int singleNumber3(int[] nums) {
        if(nums.length<=1){
            return nums[0];
        }
        int tool=0;
        for (int num : nums){
            tool=tool ^ num;
        }
        return tool;
    }

4、返回两个数组的交集II

​ 这里不仅需要返回两个数组的重复元素,并且要求重复元素的次数在数组中都是一样的。最主要的难点都是这个。
​ 方法一,就是采用的先将数组排序,然后使用两个指针。当指针所指的元素相同的时候,可以将这个数添加到list集合中,如果指针指的元素不同,就让指的较小元素的指针+1。

//方法一:使用list集合,并使用两个指针,重点是:指针指的元素不相同的时候,小的向后移动一位,大的不动
    //执行时间用时:2ms,内存消耗:41.7MB
    public int[] intersect(int[] nums1, int[] nums2) {
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        int i=0;
        int j=0;
        List<Integer> tool=new ArrayList<Integer>();
        while(i<nums1.length && j<nums2.length){
            if(nums1[i]==nums2[j]){
                tool.add(nums1[i]);
                i++;
                j++;

            }else if(nums1[i]<nums2[j]){
                i++;
            } else{
                j++;
            }
        }
        //list集合转换为数组
        int index = 0;
        int[] res=new int[tool.size()];
        for (int k = 0; k <tool.size() ; k++) {
            res[index++]=tool.get(k);
        }
        return res;
    }

​ 方法二:利用的是Java的数据结构,map集合。

//方法二:使用map集合
    //执行用时:3ms,消耗内存:41.8MB
    public int[] intersect2(int[] nums1, int[] nums2) {
        HashMap<Integer,Integer> map=new HashMap<>();
        ArrayList<Integer> list=new ArrayList<>();
        for (int i = 0; i <nums1.length ; i++) {
            //将值传入map集合中,key为数组的元素值,value为次数,一开始全都是1次
            map.put(nums1[i],map.getOrDefault(nums1[i],0)+1);
        }
        for (int i = 0; i <nums2.length; i++) {
            //循环遍历nums2数组中的元素,获取map中的value值,获取值成功后,list中添加值
            if(map.getOrDefault(nums2[i],0)>0){
                list.add(nums2[i]);
                //并将这个值减1
                map.put(nums2[i],map.get(nums2[i])-1);
            }
        }
        int[] res=new int[list.size()];
        for (int i = 0; i < list.size() ; i++) {
            res[i] = list.get(i);
        }
        return res;
    }
举报

相关推荐

0 条评论