2021.12.1 每日一题
12.1 是否含有重复元素
给定一个整数数组,判断是否存在重复元素。如果存在一值在数组中出现至少两次,那么程序打印true;如果数组中每个元素都不相同,则程序打印false ;
示例1:
输入:[1,2,3,1]
输出: true
示例2:
输入:[1,2,3]
输出: false
要求:
不可直接调用java已经封装好Arrays工具类;
严格按照用例的输入输出形式;
尽量使用多种方法解决;
可上交博客链接或直接交图片;
题解:
前引:
这题是一道简单的数组题目,解决此问题的方法较多,但大家需要注意一下输入格式的问题,应使得我们的输入停止应该是等到用户敲击回车后。
为了实现用户敲击回车为停止输入,我们可以使用两个scanner来实现。我们使用一个scanner来实现对用户输入的一行完整内容进行接收,接着接收完毕后交给另一个scanner,接着从这个scanner中使用nextInt进行取出即可;
我们原先的问题就是在于不知道用户到底会输入多少东西,而这里使用两个scanner的话,通过第一个scanner接收后,我们就知道我们输入了多少东西了,所以第二个scanner的作用就只是从流中取出原先存储的数字即可,其实我们这里就是通过将输入的数字变成字符串的形式来形成的一种动态的关系。
方法一: 暴力
暴力法
是最容易想到的方法,我们拿到给定数组的某一个数字后,去把他和数组内其他的元素进行一一比较即可,一旦出现相同打印true即可;
import java.util.Scanner;
/**
* @author xiangguang
*/
public class Test {
public static void main(String[] args) {
int[] nums = new int[2000];
Scanner scan1 = new Scanner(System.in);
String s = scan1.nextLine();
Scanner scan2 = new Scanner(s);
int index = 0;
while(scan2.hasNextLine()) {
nums[index++] = scan2.nextInt();
}
/*
* 上面为输入过程
* */
for(int i=0;i<index;i++){
for(int j=i+1;j<index;j++){
if(nums[i]==nums[j]){
System.out.println(true);
return;
}
}
}
System.out.println(false);
}
}
方法二:排序
- 这里我们可以使用基础的
选择排序,冒泡排序,插入排序或者快速排序
来对输入的数组进行排序,排序完毕后我们直接判断相邻元素之间是否相同即可; - 这里的话使用
选择排序,冒泡排序,插入排序
进行排序后再进行查找时间复杂度反而会比直接暴力的时间复杂度更高,所以这里只写出使用快速排序
的方法。
import java.util.Scanner;
/**
* @author xiangguang
*/
public class Test {
public static void main(String[] args) {
int[] nums = new int[2000];
Scanner scan1 = new Scanner(System.in);
String s = scan1.nextLine();
Scanner scan2 = new Scanner(s);
int index = 0;
while(scan2.hasNextLine()) {
nums[index++] = scan2.nextInt();
}
/*
* 上面为输入过程
* */
quicksort(nums,0,index-1); //将数组放进快排函数
//排序完毕后进行相邻元素查找
int res = nums[0];
for(int i=1;i<index;i++){
if(nums[i]==res){
System.out.println(true);
return;
}
res = nums[i];
}
System.out.println(false);
}
public static void quicksort(int[] s, int l, int r) {
if (l < r) {
int i = l, j = r, x = s[l];
while (i < j)
{
while(i < j && s[j] >= x) // 从右向左找第一个小于x的数
{
j--;
}
if(i < j) {
s[i++] = s[j];
}
while(i < j && s[i] < x) // 从左向右找第一个大于等于x的数
{
i++;
}
if(i < j) {
s[j--] = s[i];
}
}
s[i] = x;
quicksort(s, l, i - 1); // 递归调用
quicksort(s, i + 1, r);
}
}
}
方法三:HashSet去重
- 我们可以利用
HashSet
的性质,即其不会包含重复的元素来进行求解。具体的,我们对输入的数组进行一一取出元素放入HashSet
中,一旦无法添加成功则代表以前添加过此元素,则说明出现重复;
/**
* @author xiangguang
*/
public class Test {
public static void main(String[] args) {
int[] nums = new int[2000];
Scanner scan1 = new Scanner(System.in);
String s = scan1.nextLine();
Scanner scan2 = new Scanner(s);
int index = 0;
while(scan2.hasNextLine()) {
nums[index++] = scan2.nextInt();
}
/*
* 上面为输入过程
* */
HashSet<Integer> hashSet = new HashSet<Integer>();
for(int i=0;i<index;i++){
if(!hashSet.add(nums[i])){
System.out.println(true);
return;
}
}
System.out.println(false);
}
}
方法四:哈希计数
了解此法前最好先了解一下HashMap
的思想;
- 我们利用哈希计数思想使用
哈希map
来进行求解。即我们可以使用数组模拟一个哈希map
,或者直接创建一个哈希map
对用户输入的数字进行计数
,每当用户输入一个数字(即key
值)那么就给这个数字对应的个数(即value
值)进行+1处理,输入完毕后,哈希map
也存储完成,接着遍历哈希map
查看是否有value值大于等于2的即可;
使用数字模拟hashmap
,缺点是对输入的数字的大小有一定要求:
/**
* @author xiangguang
*/
public class Test {
public static void main(String[] args) {
Scanner scan1 = new Scanner(System.in);
String s = scan1.nextLine();
Scanner scan2 = new Scanner(s);
int[] hash = new int[1000];
while(scan2.hasNextLine()) {
int temp = scan2.nextInt();
hash[temp]++;
}
/*
* 上面为输入过程
* */
for(int i=0;i<hash.length;i++){
if(hash[i]>=2){
System.out.println(true);
return;
}
}
System.out.println(false);
}
}
直接创建hashmap
:
/**
* @author xiangguang
*/
public class Test {
public static void main(String[] args) {
Scanner scan1 = new Scanner(System.in);
String s = scan1.nextLine();
Scanner scan2 = new Scanner(s);
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
while(scan2.hasNextLine()) {
int temp = scan2.nextInt();
if(map.containsKey(temp)){
map.put(temp,map.get(temp)+1);
}else {
map.put(temp,1);
}
}
/*
* 上面为输入过程
* */
for(Map.Entry<Integer, Integer> entry : map.entrySet()) {
if(entry.getValue()>=2){
System.out.println(true);
return;
}
}
System.out.println(false);
}
}