/*存在重复
* 给定一个整数数组,判断是否存在重复元素。
如果任何值在数组中出现至少两次,函数返回 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);
}
}