剑指offer 28.数组中出现超过一半的数字

28.数组中出现超过一半的数字

题目描述

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。

思路一:

对数组排序,判断中间那个元素的重复度是否超过了数组长度的一半,如果超过了就是它,否则就是没有

 1 import java.util.Arrays;
 2 public class Solution {
 3     public int MoreThanHalfNum_Solution(int [] array) {
 4         if(array == null || array.length == 0){
 5             return 0;
 6         }
 7         // 排序
 8         Arrays.sort(array);
 9         // 统计中间的那个元素的个数
10         int center = array[array.length / 2];
11         int cnt = 0;
12         for(int i = 0; i < array.length; i++){
13             if(array[i] == center){
14                 cnt++;
15             }
16         }
17          
18         // 如果大于 一半则输出,否则不存在
19        return (cnt > array.length / 2) ? center : 0;
20     }
21 }

思路二: 

 采用阵地攻守的思想(另一种叫法是摩尔投票法):

记录当前重复的值和重复次数
遍历数组,如果当前元素和重复的值是同一个,重复次数加一(给它投一张支持票),否则重复次数减一(投一张反对票),重复次数减为0的时候,重复的元素更新为当前元素,重复次数置为1。
最后重复的值的变量中存储的值就有可能是出现了一半的数字。

 再加一次循环,记录这个士兵的个数看是否大于数组一般即可。

 1 import java.util.Arrays;
 2 public class Solution {
 3     public int MoreThanHalfNum_Solution(int [] array) {
 4         if(array == null || array.length == 0){
 5             return 0;
 6         }
 7         int soldier = array[0];
 8         int count = 1;
 9         for(int i = 1; i < array.length; i++){
10             if(array[i] == soldier){
11                 count++;
12             }else{
13                 count--;
14                 if(count == 0){
15                     soldier = array[i];
16                     count++;
17                 }
18             }
19         }
20         count = 0;
21         for(int i = 0; i < array.length; i++){
22             if(array[i] == soldier){
23                 count++;
24             }
25         }
26         return (count > array.length / 2) ? soldier : 0;
27     }
28 }

leetcode运行时间为:1ms, 空间为41.5MB

复杂度分析:

时间复杂度:遍历了两次数组,所以时间复杂度为O(n)

空间复杂度 :没有借助额外的空间,所以空间复杂度为O(1)

简化写法:

参考:https://leetcode-cn.com/problems/shu-zu-zhong-chu-xian-ci-shu-chao-guo-yi-ban-de-shu-zi-lcof/solution/mian-shi-ti-39-shu-zu-zhong-chu-xian-ci-shu-chao-3/

 1 class Solution {
 2     public int majorityElement(int[] nums) {
 3         // 记录当前重复的值和重复次数
 4         // 遍历数组,如果当前元素和重复的值是同一个,重复次数加一,否则重复次数减一,重复次数减为0的时候,重复的元素更新为当前元素,重复次数置为1
 5         int repVal = nums[0];
 6         int votes = 0;
 7         int len = nums.length;
 8         for(int i = 0; i < len; i++){
 9             if(votes == 0){
10                 repVal = nums[i];
11             }
12             votes += nums[i] == repVal ? 1 : -1;
13 
14         }
15         return repVal;
16     }
17 }
原文地址:https://www.cnblogs.com/hi3254014978/p/12588435.html