剑指Offer:数组中出现次数超过一半的数字Java/Python

1.题目描述

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

2.算法描述

方法1:

思想:统计所有数字出现的次数,然后检查是否存在出现次数大于数组长度一半的数字。
以数字为键,数字出现的次数为值建立一个hash表,然后以键遍历hash表,一旦出现了键对应的值大于数组长度的一半,则该键就是答案。 T ( n ) = O ( n ) , S ( n ) = O ( n ) T(n) = O(n), S(n) =O(n)

方法2:(推荐)

方法1需要开辟一个辅助hash表,有没有可能不用额外的空间呢,即 S ( n ) = O ( 1 ) S(n) =O(1) 呢?有的。
假如数组中存在一个数字出现的次数大于数组长度的一半,那么, \red{对数组中同时去掉两个不相同的数字,最后数组中剩下的数字就是出现次数最多的数字。} 当然最后找出的这个数我们需要再次遍历数组验证是否确实是出现超过数组的一半。

3.代码描述

3.1.Java代码

//方法1
import java.util.*;
public class Solution {
    public int MoreThanHalfNum_Solution(int [] array) {
        if(array == null || array.length==0)
            return 0;
        if(array.length==1)
            return array[0];
        //统计各个数字出现的次数
        Map<Integer, Integer> map = new HashMap<>();
        for(int n: array){
            map.put(n, map.getOrDefault(n, 0) + 1);
        }
        
        int ans = 0;
        for(int key: map.keySet()){
            if(map.get(key)*2>array.length){
                ans = key;
                break;
            } 
        }
        return ans;
    }
}
//方法2:
public class Solution {
    public int MoreThanHalfNum_Solution(int [] array) {
        if(array==null || array.length==0)
            return 0;
        if(array.length==1)
            return array[0];
        int num = array[0], count = 1;
        for(int i=1; i<array.length; i++){//每次遍历相邻的两个数 如果不一样 就当作将其从数组中去掉 
            if(count==0){
                num = array[i];
                count = 1;
            }
            else{
                if(num == array[i])
                    count++;
                else
                    count--;
            }
        }
        //验证是否出现次数确实是超过数组一半
        count = 0;
        for(int n: array){
            if(num == n)
                count++;
        }
        if(count*2>array.length)
            return num;
        else 
            return 0;
    }
}

3.2.Python代码

//方法1:
# -*- coding:utf-8 -*-
class Solution:
    def MoreThanHalfNum_Solution(self, numbers):
        # write code here
        if not numbers:
            return 0
        maps = {}
        for n in numbers:
            maps[n] = maps.get(n,0) + 1
        
        ans = 0
        for k, v in maps.items():
             if v*2 > len(numbers):
                    ans = k
                    break
        return ans
#方法2
# -*- coding:utf-8 -*-
class Solution:
    def MoreThanHalfNum_Solution(self, numbers):
        # write code here
        if not numbers:
            return 0
        length = len(numbers)
        if length == 1:
            return numbers[0]
        num = numbers[0]
        count = 1
        for i in range(1, length):
            if count == 0:
                num = numbers[i]
                count = 1
            else:
                if num == numbers[i]:
                    count += 1
                else:
                    count -= 1
        
        count = numbers.count(num)
        if count*2>length:
            return num
        else:
            return 0

猜你喜欢

转载自blog.csdn.net/qq_37888254/article/details/89785934