方法1:相同值+1,不同值-1
方法2:用hashmap的特点来
package jizoffe;
import java.util.*;
/*
JZ39 数组中出现次数超过一半的数字
*/
import org.omg.PortableInterceptor.INACTIVE;
import java.util.HashMap;
public class JZ39 {
public int MoreThanHalfNum_Solution(int [] array){
//第一次出现的数字次数记为1,遇到下一个如果不同次数减1,相同加1;
//最后判断出现最多的数字的次数有没有比数组长度一半多
if(array == null ||array.length == 0){
return 0;
}
int nums = array[0];
int times = 0;
for(int i = 0;i< array.length;i++){
if(times == 0 ){
nums =array[i];
times = 1;
}
else if(array[i] ==nums){
times ++;
}
else{
times --;
}
}
times = 0;
for(int i = 0;i < array.length;i++){
if(nums == array[i]){
times ++;
}
}
return times > array.length / 2 ? nums : 0;
}
// 用hashmap的思想解决
public int MoreThanHalfNum_Solution2(int [] array){
//判断给定的array长度是否为零,为零则没有这样符合条件的数字,直接return 0
if(array.length == 0){
return 0;
}
int len = array.length;
int threshold = len/2;
Map<Integer,Integer> map = new HashMap<>();
for(int i = 0; i < len; i++){
//创建一个hashmap,然后遍历这个array,hashmap的key是array里的不同数字,value是这些数字出现在array里的次数
if(!map.keySet().contains(array[i])){
map.put(array[i],1);
}else{
map.put(array[i],map.get(array[i])+1);
}
}
//遍历hashmap,检测value(即当前数字出现的次数)是否大于数组array长度的一半,
// 如果有这个数字,return回key(即当前遍历到的数字),
// 如果走完了整个hashmap还没有发现这样一个数字,需要return 0
for(Integer key: map.keySet()){
if(map.get(key) > threshold){
return key;
}
}
return 0;
}
}
思路: //思路,由于数组是递增的,将前半部分元素翻转到后面,则就形成了两个有序的子数组
//只要找到翻转的数组中小小值就是整个数组的最小值
//第一个元素肯定比最后一个元素要大,不断比较中间元素和最后一个元素大小,若中间元素大则说明最小值在后半部分
//最小值在右侧 left = mid+1 如果中间元素比右边的要小,那肯定是在最小的子数据中,则最小值在左侧
public class JZ11 {
public int minNumberInRotateArray(int [] array) {
if(array == null || array.length ==0 ){
return -1;
}
int left = 0;
int right = array.length-1;
int mid = 0;
//思路,由于数组是递增的,将前半部分元素翻转到后面,则就形成了两个有序的子数组
//只要找到翻转的数组中小小值就是整个数组的最小值
//第一个元素肯定比最后一个元素要大,不断比较中间元素和最后一个元素大小,若中间元素大则说明最小值在后半部分
//最小值在右侧 left = mid+1 如果中间元素比右边的要小,那肯定是在最小的子数据中,则最小值在左侧
while(array[left] >= array[right]){
if(right - left == 1){
mid = right;
break;
}
mid = left + ((right - left) >>1);
if(array[left] == array[right] && array[mid] == array[left] ){
//当中间值和最右边值想等时则right - 1目的是让前面一个更小值纳入计算
//case 2 2 2 1 2
int result = array[left];
for(int i = left + 1;i < right; i ++){
if(array[i] < result ){
result = array[i];
}
}
return result;
}
if(array[mid] >= array[left]){
left = mid ;
}else{
right = mid;
}
}
return array[mid];
}
}
思想1:根据题意中的数组特点优化
思想2:用二分查找的思想,减小查找区间。
public class JZ4 {
//根据题意的优化
public boolean Find(int target, int [][] array) {
if(array == null){
return false;
}
// 二维数组的行
int i = 0;
// 二维数组的的第一行最右上角
int j = array[0].length-1;
while(i < array.length && j >=0){
if(target > array[i][j]){
i ++;
} else if (target <array[i][j]){
j--;
}else{
return true;
}
}
return false;
}
//二分查找的思想
public boolean Find2(int target, int [][] array){
for(int i = 0;i<array.length;i++){
int height = array[i].length -1;
int low = 0;
int median = 0;
while (height >= low){
median = (height+low)/2;
if(target == array[i][median]){
return true;
}else if(target < array[i][median]){
height = median - 1;
}else {
low = median +1;
}
}
}
return false;
}
// 暴力求解 遍历每个元素
public boolean Find3(int target, int [][] array){
boolean flag = false;
if(array == null){
return false;
}
for(int i = 0; i < array.length;i++){
for( int j = 0;j < array[i].length;j++){
if(target == array[i][j]){
flag = true;
break;
}
}
}
if(flag){
return true;
}else{
return false;
}
}
}