Majority Number——算法练习
来源:互联网 发布:yes风淘宝客程序下载 编辑:程序博客网 时间:2024/05/17 01:47
题目:
No.1 Majority Number
Given an array of integers, the majority number is the number that occurs more than half of the size of the array. Find it.
(给定一个整型数组,找到一个数,它在数组中的出现次数大于数组元素个数的二分之一)
样例For [1, 1, 1, 1, 2, 2, 2], return 1
挑战 Expand O(n) time and O(1) space
分析:我们也许会想到先进行排序,在(n+1)/2位置的数即为要找的数,这样最小的时间复杂度为O(Nlog2N);如果进行hash,数字的范围又未知。
思路:出现的次数超过数组长度的一半,表明这个数字出现的次数比其他数字出现的次数的总和还多。所以我们可以考虑每次删除两个不同的数,那么在剩下的数中,待找数字出现的次数仍然超过总数的一半。通过不断重复这个过程,不断排除掉其他数字,最终剩下的都为同一个数字,即为要找的数字。
package test;import java.util.ArrayList;/** * * @author 风的流向 * */public class Solution { /** * @param nums * : a list of integers * @return: find a majority number */ public int majorityNumber(ArrayList<Integer> nums) { // 出现次数超过数组长度 int end = nums.size() - 1;// 最后一个元素的下标 for (int i = 1; i <= end; i++) { if (nums.get(0) != nums.get(i)) {// 如果找到和第一个元素不相等元素,则删除它们两个 nums.remove(i); nums.remove(0); end = end - 2;// 最后一个元素前进两位 i = 1;// 开始指针指向首元素 } } return nums.get(0); }}
【附:开课吧算法讨论组参考答案】
http://www.douban.com/group/topic/67690689/
解法一:O(n)时间复杂度,O(n)空间复杂度
第一种解法为采用Hash表的办法(Hash表在工作中出现的概率非常高!大家一定要熟练运用),Hash表的key是数组中的元素,而value就是这个元素对应的出现次数。
执行过程如下:利用循环依次读取数组中的数字,插入到Hash表中,插入过程中如果发现已存在该值,则对该数字对应的value进行累加1操作,如果为发现Hash表中不存在这个数字,则插入这个数字和它对应的value,value赋值1。而后判断Hash表中的计数器是否满足条件,此过程的时间复杂度为O(n),空间复杂度是O(n)。
提升:常见的Hash表的实现所占用的空间为原始数据的2倍左右,如将一个长度为n的int数组插入到Hash表中需要占用约2*n的单位空间。而Hash的实现往往是考虑冲突概率和空间占用率的一个折中,叫兽有一种Hash的简易实现方法能够在可接受的冲突率下达到1.2倍的空间占用,如有兴趣可以在后面的专题中安排讨论
参考代码:
def majorityNumber(self,nums): n = round(len(nums)/2.0) nd = {} for x in nums: if x in nd: nd[x] += 1 else: nd[x] = 1 if nd[x] >= n: return x
解法二:O(nlogn)时间复杂度,O(1)空间复杂度
第二种解法为首先对数组进行排序(导致时间复杂度为O(nlogn)),而后遍历数组,并统计相邻两个数字为相等的情况下连续发生的长度,如果这个长度满足条件,则此数字为所求结果。
参考代码:
int majorityNumber(vector<int> nums) { // write your code here std::sort(nums.begin(), nums.end()); int count = 1; int previousNum = nums[0]; for (int i = 1; i < nums.size(); i++) { if (previousNum == nums[i]) count++; else if (count > nums.size() / 2) return previousNum; else { previousNum = nums[i]; count = 1; } } return previousNum; }
解法三:
定义两个指针preIndex,postIndex,代表数组中两个元素的下标,初始化为0,1。
利用循环,比较两个指针所指向的值,如果相等,则postIndex后移一步,如果不相等,则preIndex和postIndex同时后移两步,表示‘删除’两个元素。循环结束后,返回preIndex所指向的元素。
参考代码:
/** * @param nums: a list of integers * @return: find a majority number */ public int majorityNumber(ArrayList<Integer> nums) { // write your code int preIndex = 0; //定义两个位置 int postIndex = 1; while(postIndex < nums.size() - 1){ //如果不相等,两个位置同时向后移动两步 if (nums.get(preIndex) != nums.get(postIndex)){ preIndex += 2; postIndex += 2; }else{ //后面的位置向后移动一步 postIndex += 1; } } return nums.get(preIndex); }
推荐学习内容:
时间复杂度与空间复杂度:
http://baike.baidu.com/view/7527.htm?fr=aladdin
哈希表
http://baike.baidu.com/view/329976.htm?fr=aladdin
- Majority Number——算法练习
- Majority Number II——算法练习
- LeetCode算法练习Majority Element
- Majority Number
- Majority Number
- Leetcode练习笔记——169. Majority Element
- LintCode:Majority Number / Majority Number II / Majority Number III
- LeetCode(169) Majority Number
- Lintcode - Majority Number II
- Lintcode - Majority Number III
- Majority Number II
- Majority Number I&II
- [刷题]Majority Number
- [刷题]Majority Number II
- [刷题]Majority Number III
- leetcode之majority number
- LintCode Majority Number iii
- [Lintcode]Majority Number
- JS时间倒计时
- Jquery无刷新,解析json
- phpstorm和firefox协同调试web(html)+php语句(或web(html)跳转到php语句)
- linux c/c++ 帮助 help
- PHP中$_SERVER的详细参数与说明
- Majority Number——算法练习
- Ubuntu自定义命令
- MVVM架构介绍(转)
- tomcat下中文乱码的问题
- oc中的类别
- C++ const
- 杭电hdu_1465_不容易系列之一
- UVA 10229 Modular Fibonacci (矩阵乘法+快速幂)
- uva 10070 Camel trading