• 多数元素-算法笔记总结


    算法题目

    多数元素:给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。
    你可以假设数组是非空的,并且给定的数组总是存在多数元素。

    示例 1:

    输入: [3,2,3]
    输出: 3
    

    示例 2:

    输入: [2,2,1,1,1,2,2]
    输出: 2
    

    思路分析

    解法1:暴力解法(双重循环)
    
    ​    思路:首席可以考虑暴力算法,用双重循环遍历数组可以得到每个数字的重复次数,在遍历中可以用一个变量来记录比较最大重复次数,另一个变量记录对应的数字,最后返回最大重复次数对应的数值。
    ​    分析:缺点就是时间复杂度为n平方,效率较低,优点就是思路简单直接,不会消耗多余的内存空间
    ​    思考:双重循环的时间效率低下,主要原因是会有许多重复性的操作,在此思考改进的方法,可以想象,若元素1已经得到重复次数了,后面再遇到数字1,如果再去比较明显是没有必要的,那么可以做个简单的判断,如果当前非第一个元素与上一个元素相同,就直接continue
    

    解法2:哈希map
    ​    思路:由于可以使用双重循环遍历解决问题,那么就可以想到去利用哈希快速查找的特性来降一重循环,本质就是空间换时间,思路也很直接,直接遍历一遍数组,若当前元素存在就value加一,否则就添加该元素,比较重复最大值,返回结果。
    ​    分析:时间复杂度为n级,空间复杂度也是n级。
    ​    思考:过程就是一边查找一边添加,在查找中判断重复次数是否满足条件,能够大大提高效率。
    
    解法3:投票法
    ​    思路:根据数组的特点,可以让数组中每个数值都拥有一票,数字相同,则票数相加,数字不同,则票数减一,当票数为0时,就换下一个人,由于数组一定存在多数值,那么一定存在票数大于0的数值,且该数值就是最大重复数
    ​    分析:时间复杂度为n级,不需要额外的内存空间,利用特点相应地去解题可以大大提高运行效率。
     
    
    测试用例:
        要求:数组非空,并且存在多数元素
        {0}  {5,8,5} {1,1,2,2,2,1,1}  {2,2,3,3,3}  {1,1,1} {5,4,4,4,5} {1,1,1,2,2,2,1,3,1}
    
    代码实现
    import java.util.HashMap;
    
    /**
    
    @author cosefy
    
    @date 2020/6/21
    */
    public class MajorityElement {
    public static void main(String[] args) {  //测试函数
        int[] nums = {5,4,4,4,5};
        int res1 = test1(nums);
        int res2 = test2(nums);
        int res3 = test3(nums);
        System.out.print("输入数组为: ");
        for (int num : nums) {
            System.out.print(num + " ");
        }
        System.out.println();
        System.out.println("测试一的结果是: " + res1);
        System.out.println("测试二的结果是: " + res2);
        System.out.println("测试三的结果是: " + res3);
    }
    
    //解法一:暴力解法(双重循环)
    public static int test1(int[] nums) {
        int maj = 0;
        int max_count = 0;
        for (int i = 0; i < nums.length; i++) {
            if (i != 0 && nums[i] == nums[i - 1])//此处进行简单的优化,若是当前元素(非第一个)与上一个元素相同的话,就continue
                continue;
            int count = 1;
            for (int j = i + 1; j < nums.length; j++) {
                if (nums[i] == nums[j])
                    ++count;
            }
            if (max_count < count) {  //判断当前元素的重复次数,是否大于原先的最大重复次数
                max_count = count;
                maj = nums[i];
            }
        }
        return maj;
    }
    
    //解法二:哈希map
    public static int test2(int[] nums) {
        HashMap<Integer, Integer> map = new HashMap<>();
        int len = nums.length;
        if (len==1)
            return nums[0];
        for (int i = 0; i < len; i++) {
            if (map.containsKey(nums[i])) {
                map.put(nums[i], map.get(nums[i]) + 1);
                if (map.get(nums[i]) > len / 2) //此处进行判断,可以提高时间效率
                    return nums[i];
            } else
                map.put(nums[i], 1);
        }
        return 0;  //由于数组说明了一定存在多数元素,for循环里的return会执行,此处的return不会执行。
    }
    
    //解法三:投票法
    public static int test3(int[] nums) {
        if (nums.length == 1)
            return nums[0];
        int count = 1;
        int cur = nums[0];
        for (int i = 1; i < nums.length; i++) {
            if (count > 0) {
                if (cur == nums[i])
                    ++count;
                else
                    --count;
            } else {              //此时count为0,换下一个数字,并把count置为1
                cur = nums[i];
                count =1;
            }
    
    ​    }
    ​    return cur;
    }
    }
    
  • 相关阅读:
    DS博客作业06——图
    DS博客作业05——树
    DS博客作业03——栈和队列
    DS博客作业02--线性表
    DS博客作业01--日期抽象数据类型设计与实验
    C语言课设——电影院选票系统
    C语言博客作业06——结构体&文件
    C语言博客作业05——指针
    DS博客作业08--课程总结
    DS博客作业07--查找
  • 原文地址:https://www.cnblogs.com/cosefy/p/13176212.html
Copyright © 2020-2023  润新知