• 剑指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 }
  • 相关阅读:
    电子证书 DER & PEM & CRT & CER
    更新显卡驱动
    隐马尔可夫模型拼音汉字输入法
    隐马尔可夫模型:HMM
    numpy 随机产生数字
    python(62):保留两位小数
    训练的时候 nvidia:自动刷新
    python(61):str 和 bytes 转换
    tensorflow 笔记12:函数区别:placeholder,variable,get_variable,参数共享
    tensorflow 笔记11:tf.nn.dropout() 的使用
  • 原文地址:https://www.cnblogs.com/hi3254014978/p/12588435.html
Copyright © 2020-2023  润新知