leetcode——169.多数元素(多解法)

169. 多数元素

题目描述

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

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

示例 1:
输入:nums = [3,2,3]
输出:3

示例 2:
输入:nums = [2,2,1,1,1,2,2]
输出:2

提示:
n == nums.length
1 <= n <= 5 * 10^4
-10^9 <= nums[i] <= 10^9

进阶:尝试设计时间复杂度为 O(n)、空间复杂度为 O(1) 的算法解决此问题。

哈希表解法

使用哈希表来记录数组中元素出现的次数。

哈希表的基本用法

首先,我们需要了解一下哈希表的基本用法。

import java.util.HashMap;
import java.util.Map;public class HashTableDemo {public static void main(String[] args) {// 创建一个哈希表Map<String, Integer> map = new HashMap<>();// 添加一个键值对map.put("apple", 1);System.out.println("HashMap: " + map); //正确输出: HashMap: {apple=1}// 检查一下这个键是否在哈希表中boolean exists = map.containsKey("apple");System.out.println("Contains 'apple' key: " + exists); //正确输出: Contains 'apple' key: true// 获取这个键对应的值Integer value = map.get("apple");System.out.println("Value for 'apple': " + value); //正确输出: Value for 'apple': 1// 在哈希表中删掉这个键map.remove("apple");System.out.println("HashMap after remove: " + map); //正确输出: HashMap after remove: {}// 添加一些键值对map.put("banana", 2);map.put("cherry", 3);System.out.println("HashMap: " + map); //正确输出: HashMap: {banana=2, cherry=3}// 输出哈希表中的键值对for(Map.Entry<String, Integer> entry : map.entrySet()) {System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());}//正确输出: Key = banana, Value = 2//                 Key = cherry, Value = 3// 输出哈希表的键值对个数int size = map.size();System.out.println("Size of HashMap: " + size); //正确输出: Size of HashMap: 2}
}

用到的方法:
创建

Map<,> map = new Hash<>();

检查是否包含

boolean con = map.containsKey(key);

插入更新键值对

map.put(key, value);

哈希解法代码

class Solution {private Map<Integer, Integer> count(int[] nums) {Map<Integer, Integer> map = new HashMap<Integer, Integer>();for(int i = 0; i < nums.length; i++) {// 如果哈希表中未包含这个数字if(! map.containsKey(nums[i])) {// 则添加这个数字,对应的次数为1map.put(nums[i], 1);} else {// 否则更新这个数字的次数加一map.put(nums[i], map.get(nums[i]) + 1);}}return map;}public int majorityElement(int[] nums) {Map<Integer, Integer> map = count(nums);for(Integer key : map.keySet()) {// 遍历哈希表,若次数大于n/2,就返回对应的数字if(map.get(key) > nums.length/2) return key;}// 找不到多数元素返回0return 0;}
}

排序

思路

排序解法的难点在于理解算法思路,而不是代码过程。
因为题目说多数元素的个数必大于n/2
那么将代码升序(或降序)排序之后,多数元素必定会在数组的中间点。

可以这样想象,如果你把数组按照升序或者降序排列,那么多数元素由于数量超过半数,就一定会占据数组中间的位置。无论它在前半部分的数量还是在后半部分的数量,由于它的数量超过了总数的一半,因此它肯定会延伸到数组的中间,也就是中位数的位置。
比如考虑一个由 7 个元素组成的数组 [2, 2, 2, 2, 5, 5, 5],其中出现最多的元素就是 2,数量为 4 > 7/2,排序后得到的数组是 [2, 2, 2, 2, 5, 5, 5],你可以看到元素 “2” 在数组的中间。
这就是为什么在排序后,多数元素会出现在数组的中间。因此,只需要返回排序后数组的中位数就好。在编程实现上,这通常意味着返回索引为 n/2 的元素(在 Java 中,数组的索引从 0 开始)。

代码

class Solution {public int majorityElement(int[] nums) {Arrays.sort(nums);return nums[nums.length/2];}
}

这里面用到了Arrays类的一个方法,即排序方法Arrays.sort(),参数是数组,默认升序排序。

分治法

思路

分治法的过程 : 先分解,后合并。
也就是将数组分成两半,两个子问题来处理,然后再将两个子问题得到的结果合并,得到大问题的答案。

对应在这个问题当中,可以得到
大问题:求整个数组的多数元素
子问题:将数组进行划分,左右两个子数组的多数元素
然后再依次进行划分直到子数组的长度为一时,则唯一的元素就是它的多数元素,进行返回,也就是递归条件

代码

基于这里,可以得到我们的递归函数中划分部分代码

private int Rec(int[] nums, int start, int end) {// 当数组只有一个元素时,结束递归if(start == end) return nums[start];// 算出中间点,进行划分int mid = (start + end) /2;// 得到左子数组的多数元素int left = Rec(nums, start, mid);// 得到右子数组的多数元素int right = Rec(nums, mid, end);// 合并过程}

加上合并即全部代码:

class Solution {// 计算子数组中多数元素出现的个数private int count(int[] nums, int start, int end, int num){int count = 0;for(int i = start; i <= end; i++) {if(nums[i] == num) count++;}return count;}private int Rec(int[] nums, int start, int end) {// 当数组只有一个元素时,结束递归if(start == end) return nums[start];// 算出中间点,进行划分int mid = (start + end) /2;// int mid = (end - start) / 2 + start;// 得到左子数组的多数元素int left = Rec(nums, start, mid);// 得到右子数组的多数元素// 注意这里起点时mid+1int right = Rec(nums, mid+1, end);// 合并过程// 若左右子数组的多数元素相同,则直接返回if(left == right) return left;// 否则算出左右多数元素在整个数组出现的次数,次数多的则是大数组的多数元素int leftcount = count(nums, start, end, left);int rightcount = count(nums, start, end, right);// if(leftcount > rightcount) return left;// else return right;return leftcount > rightcount ? left : right;}public int majorityElement(int[] nums) {return Rec(nums, 0, nums.length-1);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/16378.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在CentOS7上安装Oracle11

一、概述 Oracle有两种安装方式&#xff0c;桌面安装和静默安装。这里我采用桌面安装的方式。 不得不说&#xff0c;Oracle真的是我目前为止安装过的最麻烦的软件没有之一&#xff0c;比K8S还麻烦&#xff0c;Oracle&#xff0c;真有你的&#xff01;废话不多说&#xff0c;臭…

【Nginx <末>】Nginx 基于 IP 地址的访问限制

目录 &#x1f44b;前言 &#x1f4eb;一、限制 IP 可以实现哪些功能 &#x1f440;二、 项目实现 2.1 访问控制实现 2.2 Nginx 配置中指定 IP 地址 &#x1f49e;️三、章末 &#x1f44b;前言 小伙伴们大家好&#xff0c;前面一段时间学习了 Nginx 的相关知识&#xff0c…

实现排行榜之Mysql的 OrderBy方法

排行榜之Mysql OrderBy实现 1、排行榜系统的功能点 数据收集与计算 排名规则 实时性 可视化展示 周期性更新 2、排行榜系统基本功能要素 MySQL实现方案 数据量较小&#xff0c;业务场景比较简单。可直接使用 新建表 CREATE TABLE leaderboard( id BIGINT UNSIGNED NOT …

《Python源码剖析》之pyc文件

前言 前面我们主要围绕pyObject和pyTypeObject聊完了python的内建对象部分&#xff0c;现在我们将开启新的篇章—python虚拟机&#xff0c;将聚焦在python的执行部分&#xff0c;搞懂从“代码”到“执行”的过程。开启新的篇章之前&#xff0c;你也许会有一个疑惑&#xff1a;我…

【Python】 XGBoost vs LightGBM:两大梯度提升框架的对比

原谅把你带走的雨天 在渐渐模糊的窗前 每个人最后都要说再见 原谅被你带走的永远 微笑着容易过一天 也许是我已经 老了一点 那些日子你会不会舍不得 思念就像关不紧的门 空气里有幸福的灰尘 否则为何闭上眼睛的时候 又全都想起了 谁都别说 让我一个人躲一躲 你的承诺 我竟然没怀…

泰拉瑞亚从零开始的开服教程

前言 本教程将讲诉使用Linux系统搭建泰拉瑞亚服务器&#xff08;因为网上已经有很完善的windows开服教程了&#xff09;&#xff0c;使用的Linux发行版是Debian11,服务端使用的程序是TShock&#xff0c;游戏版本是1.4.4.9 所需要准备的 一台服务器&#xff08;本教程使用的是…

tldk之tle简单记录

文章目录 1.tle简介2.tle处理tcp3.tle处理udp4.tle封装包头 项目中遇到了tldk中tle的使用&#xff0c;不太熟悉&#xff0c;这里记录一下&#xff0c;方便以后回顾 tldk源码位置&#xff1a; tldk源码 简单理解&#xff1a;这里我们项目大概dpdk从网卡收到数据包之后&#xff…

解决Jupyter运行代码显示Kernel Restarting的错误

在Jupyter notebook上运行代码时发现如下错误&#xff1a; 使用VS Code运行在日志表中发现错误存在&#xff1a; 它表明在初始化"libiomp5md.dll"库时发生问题&#xff0c;因为该库已经被初始化过了&#xff0c;这个错误可能是由于程序中重复初始化OpenMP库导致的&am…

深入探索C++ Vector容器:灵活的动态数组秘籍

目录 ​编辑 引言 一、初识vector&#xff1a;构造与初始化 二、动态管理&#xff1a;添加与删除元素 三、访问与遍历&#xff1a;多种方式直达元素 四、容量与大小&#xff1a;动态调整的艺术 五、进阶技巧&#xff1a;高效运用vector 结语 引言 在C编程的世界里&…

驱动命令之insmod depmod modprobe rmmod modinfo lsmod

insmod命令 insmod需指定所需加载模块的路径&#xff0c;且只加载所指定的模块&#xff0c;如果所指定的模块依赖于其他模块&#xff0c;insmod不会自动添加&#xff1b; 语法 insmod [-fkmpsvxX][-o <模块名称>][模块文件][符号名称 符号值] 参数说明&#xff1a; -f…

微信小程序如何跳转微信公众号

1. 微信小程序如何跳转微信公众号 1.2. 微信公众号配置 登录微信公众号&#xff0c;点击【小程序管理】&#xff1a;   点击【添加】&#xff1a;   点击【关联小程序】&#xff1a;   输入小程序进行关联&#xff1a; 1.2. 微信小程序配置 登录微信小程序&#xf…

vue-router配置路由重定向不生效问题

概述 在做前端vue项目测试时&#xff0c;发现在路由配置中配置访问地址“http://ip:port/” 重定向到某个地址时&#xff0c;界面没有显示重定向后的地址。 能保证的是我的vue写法绝对没错。 简要代码 App.vue: <template><div id"app"><rout…

SQL注释方法 -- 单行注释/多行注释

三种注释方法 # 注释同行后面的内容&#xff1b; /* */ 注释中间的内容&#xff0c;可多行&#xff1b; -- 行注释&#xff0c;-- 后必须加空格。 # 注释同行后面的内容&#xff1b;/* 注释中间的内容&#xff0c; 可多行&#xff1b; */ -- 行注释&#xff0c;-- 后…

Django之Ajax实战笔记--城市级联操作

1. 项目架构搭建 1.1 创建项目tpdemo,创建应用myapp # 创建项目框架tpdemo$ django-admin startproject tpdemo$ cd tpdemo# 在项目中创建一个myapp应用$ python manage.py startapp myapp# 创建模板目录$ mkdir templates$ mkdir templates/myapp$ cd ..$ tree tpdemotpdemo…

HTTP的由来以及发展史

HTML&HTML5的学习探索 01、Html的由来和发展史 01-01、Html的由来 HTML的英文全称是 Hypertext Marked Language&#xff0c;即超文本标记语言。HTML是由Web的发明者 Tim Berners-Lee&#xff08;蒂姆伯纳斯李&#xff09;于1990年创立的一种标记语言&#xff0c; 他是万…

Sip协议(一)

Sip协议(一) 本文主要介绍sip协议 1: 简介 ​ SIP&#xff08;Session Initiation Protocol&#xff0c;会话发起协议&#xff09;是一种应用层协议&#xff0c;它被广泛应用于VoIP&#xff08;Voice over Internet Protocol&#xff0c;互联网语音通信&#xff09;中。 ​…

返回枚举类给前端

1. 前言 在实际开发过程中&#xff0c;前端的下拉框或者单选按钮的内容通常的需要和后端匹配的&#xff0c;故一般会由后端将下拉框的内容或单选框的内容传给前端&#xff0c;而这些内容在后端一般是由枚举类存储的&#xff0c;如果后端直接返回枚举类&#xff0c;返回结果将会…

K-means聚类算法详细介绍

目录 &#x1f349;简介 &#x1f348;K-means聚类模型详解 &#x1f348;K-means聚类的基本原理 &#x1f348;K-means聚类的算法步骤 &#x1f348;K-means聚类的优缺点 &#x1f34d;优点 &#x1f34d;缺点 &#x1f348;K-means聚类的应用场景 &#x1f348;K-mea…

SQL Server2019安装步骤教程(图文)_最新教程

一、下载SQL Server2019 1.到微软官网下载SQL Server Developer版本&#xff0c;官网当前的2019版本下载需要注册账号。 不想注册的朋友&#xff0c;可以选择从网盘下载&#xff1a;点击此处直接下载 2.下载之后先解压&#xff0c;解压后执行exe安装程序。打开之后的界面如下…

学 Java 具体能干什么?

学习 Java 后&#xff0c;你可以从事许多不同的工作和项目&#xff0c;涵盖了广泛的应用领域。以下是一些具体的应用场景和工作方向&#xff1a; 1. 企业级应用开发 Java 是企业级应用开发的首选语言之一&#xff0c;特别适合开发大规模、分布式、多层次的企业应用程序。 Jav…