Leetcode算法之查询数组中所有出现次数满足一定条件的元素

256 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

Leetcode 169题 多数元素

题目描述:

Problem Describe

给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

题目分析:

Problem Analysis

提炼出本题的关键点,总结如下:

1、数组存在多个整数元素

2、其中某个数值在这个数组中出现的次数大于 ⌊ n/2 ⌋次

常规的思路:牺牲空间代价,创建一个可以保存每个数值出现次数的集合。最好的选择是HashMap数组,能够使用键值对将数值和次数关联在一起。格式为:<数值: 次数>

按照元素统计次数,可定义式子如下:

U=xx=a,b,c,a,a,...A=xx=ax>f(x)f(x)={1,x=a0,x!=aU = {x | x = a, b, c, a, a, ...}\\ A = {x | x = a 且 x -> f(x) }\\ f(x) = \begin{cases} 1 &{, x=a}\\ 0&{, x != a} \end{cases}

常规思路代码:

class Solution {
    public int majorityElement(int[] nums) {
        Map<Integer, Integer> map = new HashMap();
       for(int i = 0; i < nums.length; i++) {
           int val = map.get(nums[i]) == null ? 0 : map.get(nums[i]);
           if(val != 0) {
               val++;
           } else {
               val = 1;
           }
           map.put(nums[i], val);
           if(val > nums.length / 2) {
               return nums[i];
           }
       }
       return 0;
    }
}

是否能够在不申请HashMap空间的情况下,把这个在数组中占有 ⌊ n/2 ⌋ 的元素找到?

答案是肯定可以的。可以定义一个元素,用于保存这个重复值,定义count用于计算该元素出现的次数。遍历取出数组的元素,进行下面的比较:

(1)当出现的是临时空间(哨兵)所保存的数值时,就将count值加1;

(2)若不是这个元素值,且计数的count值为0,则这个哨兵保存从数组取出的这个新值,且将count值置为1

(3)若不是哨兵所保存的元素值,且计数的count值大于0,则将count值减1,以表示两个数之间产生了抵消(比较两个元素哪个次数多,可以对他们)

完整代码:

class Solution {
    public int majorityElement(int[] nums) {
       int count = 1;
       int replica = nums[0];
       for(int i = 1; i < nums.length; i++) {
           if(replica == nums[i]) {
               count++;
           } else if(count <= 0) {
               count++;
               replica = nums[i];
           } else {
                count--;
           }
       }
       return replica;
    }
}