1. 数组中只出现一次的数字
1.1 题目描述
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
1.2 核心代码实现
import java.util.*;
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
if(array == null || array.length <= 1){
return;
}
/*
//方法一:先排序再两两比较
Arrays.sort(array); //先将数组排序
int i = 0, j = 0;
int[] res = new int[2]; //新建数组res存储原数组只出现一次的数字
while(i < array.length - 1){ //依次判断当前位置与下一位置的数字是否相同
if(array[i] == array[i+1]){ //若相等则直接跳过,继续比较下一对
i = i + 2;
}else{ //若不同则将当前位置的数字保存到res中
res[j++] = array[i];
i++;
}
}
if(i == array.length - 1){ //数组中的最后一个数只出现一次
res[1] = array[i];
}
num1[0] = res[0];
num2[0] = res[1];
*/
/*
//方法二:借助ArrayList
ArrayList<Integer> list = new ArrayList<>();
for(int i = 0; i < array.length; i++){
if(!list.contains(array[i])){
list.add(array[i]);
}else{
list.remove(Integer.valueOf(array[i]));
}
}
num1[0] = list.get(0);
num2[0] = list.get(1);
*/
/*
//方法三:位运算
//位异或^:若数A与B不同,则异或结果为1,相同则为0;位与&:若A与B两个数相同,则为1,否则为0
int index = array[0];
for(int i = 1; i < array.length; i++){
index ^= array[i];
}
int classify = index & (-index);
for(int i = 0; i < array.length; i++){
if((array[i] & classify) == 0){
num1[0] ^= array[i];
}else{
num2[0] ^= array[i];
}
}
*/
//方法四:哈希
HashMap<Integer,Integer> hashMap=new HashMap<>();
for (int i : array) {
//foreach语句:自动遍历数组中的每个元素
if(hashMap.get(i) == null){
hashMap.put(i, 1);
}else{
hashMap.remove(i);
}
}
Set<Integer> set = hashMap.keySet(); //获取键的set集合
Iterator<Integer> iterator = set.iterator(); //迭代遍历
num1[0] = iterator.next();
num2[0] = iterator.next();
}
}
新增方法如下:
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param array int整型一维数组
* @return int整型一维数组
*/
public int[] FindNumsAppearOnce (int[] array) {
Arrays.sort(array);
/*方法一
int max = array[array.length - 1];
int[] helpArray = new int[max + 1];
for(int i = 0; i < array.length; i++){
for(int j = 0; j < helpArray.length; j++){
if(array[i] == j){
helpArray[j]++;
break;
}
}
}
int count = 0;
int[] res = new int[2];
for(int i = 0; i < helpArray.length; i++){
if(helpArray[i] == 1){
count++;
res[count - 1] = i;
}
}
return res;
*/
//方法二
int i = 0, j = 1;
int count = 0;
int[] res = new int[2];
while(i < array.length - 1){
if(array[i] != array[j]){
count++;
res[count - 1] = array[i];
i = i + 1;
j = i + 1;
}else{
i = i + 2;
j = i + 1;
}
}
if(i == array.length - 1) res[1] = array[i];//最后一位数只出现一次
return res;
}
}
2. 数组中出现次数超过一半的数字
2.1 题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
2.2 示例1
输入
[1,2,3,2,2,2,5,4,2]
返回值
2
2.3 核心代码实现
import java.util.*;
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
if(array == null || array.length == 0) return 0;
/*方法一:先将数组元素排序
Arrays.sort(array);
int num = array[array.length / 2];
int count = 0;
for(int i : array){
if(num == i) count++;
}
if(count > array.length / 2) return num;
return 0;
*/
/*方法二:先将数组元素存入map
Map<Integer, Integer> map = new HashMap<>();
for(int i : array){
if(map.containsKey(i)){
map.put(i, map.get(i) + 1);
}else{
map.put(i, 1);
}
}
//遍历map
for(Map.Entry<Integer, Integer> entry : map.entrySet()){
if(entry.getValue() > array.length / 2){
return entry.getKey();
}
}
return 0;
*/
//方法三
int len = array.length;
int[] arr = new int[len + 1];
for(int i = 0; i < len; i++){
arr[array[i]]++;
}
for(int i = 0; i < arr.length; i++){
if(arr[i] > len / 2) return i;
}
return 0;
}
}