Leecode初级——数组篇2(存在重复、只出现一次的数字、两个数组的交集)

/*存在重复
* 给定一个整数数组,判断是否存在重复元素。
如果任何值在数组中出现至少两次,函数返回 true。如果数组中每个元素都不相同,则返回 false。
示例 1:
输入: [1,2,3,1]
输出: true

示例 2:
输入: [1,2,3,4]
输出: false

示例 3:
输入: [1,1,1,3,3,4,3,2,4,2]
输出: true
* */
package com.primary.Aarray;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class Solution4 {

    /*方法一:常规,两层循环,依次比较*/
    public boolean containsDuplicate(int[] nums) {
        boolean judge;
        int len=nums.length;
        for (int i=0;i<len;++i){
            for (int j=i+1;j<len;++j){
                if (nums[i]==nums[j]){
                    judge=true;
                    return judge;
                }
                else continue;
            }
        }
        return false;
    }
    /*方法二:先排序,后在遍历数组时每次与下一个做比较,若存在相等则存在重复*/
    public boolean containsDuplicate1(int[]nums){
        int len=nums.length;
        Arrays.sort(nums);
        for (int i=0;i<len-1;++i){
            if (nums[i]==nums[i+1]){
                return true;
            }
        }
        return false;

    }

    /*
    * 利用HashSet的唯一性,在每次添加的时候检查返回值来进行判断
    * 虽然效率上和空间上都没有上面的方法好,但是这种可以适用于很多判断重复的问题,它不仅仅适用于基本数据类型,也可以用在判断对象的重复。可以说是种万精油的方法吧
    * */
    public boolean containsDuplicate2(int[]nums){
        Set save=new HashSet();
        for (int a:nums){
            if (!save.add(a))
                return true;
        }
        return false;

    }

    public static void main(String[] args){
        int[] nums={1,2,3,4,5,6,1,2,5,8,9,6};
        int[]nums1={1,2,3,4,9,10,44,88,5,6,7};
        Solution4 solution4=new Solution4();
        boolean judge=solution4.containsDuplicate(nums);
        System.out.println("方法1:\n"+judge);
        judge=solution4.containsDuplicate(nums1);
        System.out.println(judge);

        System.out.println("方法2:\n"+solution4.containsDuplicate1(nums));
        System.out.println(solution4.containsDuplicate1(nums1));

        System.out.println("方法3:\n"+solution4.containsDuplicate2(nums));
        System.out.println(solution4.containsDuplicate2(nums1));
    }
}


=============================================================================================
/* 只出现一次的数字!!!
*最佳方法:异或法!!
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1]
输出: 1

示例 2:
输入: [4,1,2,1,2]
输出: 4
* */
package com.primary.Aarray;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class Solution5 {
    /*1.比较法*/
    public int singleNumber1(int[] nums) {
        Arrays.sort(nums);//先排序
        /*for (int i=0;i<nums.length;i+=2){
            if (i==0){
                if (nums[i]!=nums[i+1])
                    return nums[i];
            }
            else if (i==nums.length-1){
                if (nums[i]!=nums[i-1])
                    return nums[i];
            }
            else {
                if (nums[i] != nums[i - 1] && nums[i] != nums[i + 1])
                    return nums[i];
            }
        }

        return nums[nums.length-1];*/
        //改进方法
        for (int i=0;i<nums.length-1;i=i+2){
            if (nums[i]!=nums[i+1]){
                return nums[i];
            }
        }
        return nums[nums.length-1];
    }

    /*2.去重法*/
    //思路:利用HashSet的特性,删除重复的数组元素,最后剩下一个单独的元素,返回即可。
    public int singleNumber2(int[]nums){
        Set set=new HashSet();
        for (int i=0;i<nums.length;++i){
            if (!set.add(nums[i])){
                set.remove(nums[i]);
            }
        }
        return (int) set.iterator().next();
    }

    /*
    * 3.(求差法):思路:先对数组排序,显而易见的,单独出现一次的数据必然是出现在数组下标为偶数的位置(下标从0开始),那么所有奇数下标的元素之和减去偶数下标的元素之和,就是需要求得的结果。
    * */
    public int singleNumber3(int []nums){
        int sumO=0;//奇数和
        int sumE=0;//偶数和
        Arrays.sort(nums);
        for (int i=0;i<nums.length;++i){
            if (i%2==0)
                sumE+=nums[i];
            else sumO+=nums[i];
        }
        return sumE-sumO;
    }
    /*最佳!!!
    * 4.异或法:
  思路:根据异或运算的特点,相同的数字经过异或运算后结果为0,除单独出现一次的数字外,其他数字都是出现两次的,那么这些数字经过异或运算后结果一定是0。而任何数字与0进行异或运算都是该数字本身。所以对数组所有元素进行异或运算,运算结果就是题目的答案。
    * */
    public int singleNumber4(int[] nums){
        int n=0;
        for (int i=0;i<nums.length;++i){
            n=n^nums[i];
        }
        return n;
    }


    public static void main(String[] args){
        int []nums1={8,9,8,9,4,1,2,10,2,1,4};
        int []nums2={8,9,8,9,4,1,2,10,2,1,4};
        int []nums3={8,9,8,9,4,1,2,10,2,1,4,10,99};
        int []nums4={1,2,5,6,5,6,2,1,88,8,9,8,9};
        Solution5 solution5=new Solution5();
        int singleNum1=solution5.singleNumber1(nums1);
        System.out.println("1.single number="+singleNum1);

        int singleNum2=solution5.singleNumber2(nums2);
        System.out.println("2.single number="+singleNum2);

        int singleNum3=solution5.singleNumber3(nums3);
        System.out.println("3.single number="+singleNum3);

        int singleNum4=solution5.singleNumber4(nums4);
        System.out.println("4.single number="+singleNum4);

        /*Set和iterator使用*/
        Set setTest=new HashSet();
        int n;
        for (int i=0;i<10;++i){
            setTest.add(i);
        }
        Iterator<Integer> iterator=setTest.iterator();
        while (iterator.hasNext()){
            System.out.print(iterator.next());
        }
    }

}

==================================================================================

/*两个数组的交集 II!!!!!
* 给定两个数组,编写一个函数来计算它们的交集。
示例 1:
输入: nums1 = [1,2,2,1], nums2 = [2,2]
输出: [2,2]

示例 2:
输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出: [4,9]
说明:
输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。
我们可以不考虑输出结果的顺序。
进阶:
如果给定的数组已经排好序呢?你将如何优化你的算法? 3
如果 nums1 的大小比 nums2 小很多,哪种方法更优?
如果 nums2 的元素存储在磁盘上,磁盘内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?
* */
package com.primary.Aarray;

import java.lang.reflect.Array;
import java.util.*;

public class Solution6 {

    /*
    * 1.思路:
  1、增加一个计数器,用来记录其中一个数组元素出现的次数。
  2、遍历另一个数组,如果该数组元素在计数器中有记录且记录的次数大于1,将该数字新增到结果数组中,同时计数器该数字记录的次数减1。
    * */
    public int[] intersect1(int[] nums1, int[] nums2) {
        Map<Integer, Integer> counter = new HashMap<>(); //计数器,key为数组中的数字,value为该数字在数组中出现的次数
        for (int i = 0; i < nums1.length; i++) {
            int num = nums1[i];
            if (counter.containsKey(num)) {
                counter.put(num, counter.get(num) + 1);
            } else {
                counter.put(num, 1);
            }
        }
        List<Integer> tempList = new ArrayList<>();
        for (int i = 0; i < nums2.length; i++) {
            int num = nums2[i];
            if (counter.containsKey(num) && counter.get(num) > 0) {
                counter.put(num, counter.get(num) - 1); //计数器中记录该数字的次数减1
                tempList.add(num); //将该数字添加到list中
            }
        }

        //为满足题目返回值类型,将list转换为int数组

        System.out.print("方法1:");
        return Result(tempList);
    }

    //2.给数组设置标志位
    public int[] Intersect2(int[] nums1,int[] nums2){
        boolean[] jdg=new boolean[nums2.length];
        List<Integer>list=new ArrayList<>();
        for (int i=0;i<nums1.length;++i){
            for (int j=0;j<nums2.length;++j){
                if (nums1[i]==nums2[j]&&jdg[j]==false){
                    list.add(nums1[i]);
                    break;
                }
            }
        }

        System.out.print("\n方法2:");
        return Result(list);
    }

    //3.排序好后比较位置指针
    public int[] Intersect3(int[] nums1,int[] nums2){
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        List<Integer>list=new ArrayList<>();
        for (int i=0;i<nums1.length;++i){
            for (int j=i;j<nums2.length;++j){
                if (nums1[i]==nums2[j]){
                    list.add(nums1[i]);
                    break;
                }
            }
        }
        System.out.print("\n方法3:");
        return Result(list);

    }
    public int[] Result(List<Integer>list){
        int[] result=new int[list.size()];
        int counter=0;
        for (int i:list
        ) {
            System.out.print(i+" ");
            result[counter]=i;
            counter++;
        }
        return result;
    }

    public static void main(String[] args){
        int []nums1={4,9,5,4,4,5};
        int []nums2={9,4,9,8,4};
        Solution6 solution6=new Solution6();
        solution6.intersect1(nums2,nums1);

        int[] nums3={4,4,9,6,5,1};
        int[] nums4={4,9,8,5,9,6,4,1,4,1,4};
        solution6.Intersect2(nums3,nums4);

        int[] nums5={4,9,5};
        int[] nums6={9,4,9,8,4};
        solution6.Intersect3(nums5,nums6);


    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值