`
gwmwhu
  • 浏览: 63242 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

寻找多数元素

 
阅读更多

今天实现的算法是寻找多数元素,多数元素是指在一个含有n个元素的序列中出现次数多于[n/2](向下取整)的元素。

蛮力寻找多数元素是对每个元素进行计数,如果某个元素的计数超过[n/2],则断言它是多数元素,否则不存在多数元素。这种方法的时间复杂度过高,可以寻找更高性能的算法解决这类问题。

如果一个序列存在多数元素,那么该多数元素一定是该序列排序后的中间元素,也就是第[n/2](向上取整)个元素。所以可以通过寻找一个序列的中间元素,然后判断该元素是否为多数元素来寻找多数元素。对于此方法,有一个结论可以使用:

在原序列中去除两个不同元素后,那么在原序列中的多数元素在新序列中还是多数元素。

这个结论可以支持一个寻找多数元素候选者的算法,该算法的伪代码如下:

算法:CANDIDATE

输入:n个元素的数组A[1...n]

输出:多数元素的候选元素

candidate(m)

 

j ← m
c ← A[m]
count ← 1
while j < n and count > 0:
    j ← j + 1
    if A[j] = c then
        count = count + 1
    else
        count = count - 1
    end if
end while
if j == n then return c
else return candidate(j+1)

 

  在寻找到候选多数元素后,只需要对该元素进行计数,判断是否为多数元素,该算法伪代码如下:

算法:MAJORITY

输入:n个元素的数组A[1...n]

输出:若存在多数元素,则输出;否则输出none

 

c ← candidate(1)
count ← 0
for j ← 1 to n:
    if A[j] == c then
        count = count + 1
    end if
end for
if count > [n/2] then return c
else return none

 

 下面是三种代码的实现,首先是C++版本:

 

#include <iostream>
#define Type int
#define NONE INT_MIN 

using namespace std;

Type candidate(Type *a, int n, int m) {
    int j = m;
    Type c = a[m];
    int count = 1;
    while (j < n && count > 0) {
        j ++;
        if (a[j] == c) {
            count ++;
        }else {
            count --;
        }
    }
    if (j == n) {
        return c;
    }else {
        return candidate(a, n, j+1);
    }
}

//输入数组必须有n+1个元素,第0个元素不使用,元素为1..n
//若存在多数元素,则返回多数元素的值,若不存在则返回NONE 
Type Majority(Type *a, int n) {
    Type c  = candidate(a, n, 1);
    int count = 0;
    for (int j = 1; j <= n; j ++) {
        if (a[j] == c) {
            count ++;
        }
    }
    if (count > n/2) {
        return c;
    } else {
        return NONE;
    }
}

int main(void) {
    Type a[14] = {0, 1, 2, 5, 5, 5, 4 ,3 ,2, 5, 5, 4, 5, 5}; 
    
    cout << "输入数组为:\n"; 
    for (int i = 1; i <= 13; i ++) {
        cout << a[i] << "  ";
    }
    cout << endl;
    cout << "多数元素为:\n" << Majority(a, 13) << endl;
    
    getchar();
    return 0;
}

 

 然后是Java代码:

 

import java.util.ArrayList;


public class MajorityList {
	private ArrayList<Integer> list = new ArrayList<Integer>();
	private boolean hasMajority = false;
	private int majority_value = 0;

	/**
	 * 构造函数,使list从第1个元素开始保存,而不是第0个
	 */
	public MajorityList() {
		list.add(0);
	}
	
	/**
	 * 寻找候选者
	 * @param m 
	 * @return 返回可能的多数元素
	 */
	private int candidate(int m) {
		int j = m;
	    int c = list.get(m);
	    int count = 1;
	    while (j < list.size()-1 && count > 0) {
	        j ++;
	        if (list.get(j) == c) {
	            count ++;
	        }else {
	            count --;
	        }
	    }
	    if (j == list.size()-1) {
	        return c;
	    }else {
	        return candidate(j+1);
	    }
	}
	
	/**
	 * 判断候选者是否为多数元素
	 */
	private void majority() {
		int c  = candidate(1);
	    int count = 0;
	    for (int j = 1; j <= list.size()-1; j ++) {
	        if (list.get(j) == c) {
	            count ++;
	        }
	    }
	    if (count > (list.size()-1)/2) {
	    	hasMajority = true;
	    	majority_value = c;
	    } else {
	    	hasMajority = false;
	    	majority_value = 0;
	    }
	}
	
	public void add(int x) {
		list.add(x);
		hasMajority = false;
		majority_value = 0;
	}
	
	public boolean hasMajorityElement() {
		majority();
		return hasMajority;
	}
	
	public int getMajorityElement() {
		return majority_value;
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int [] a = {1, 2, 5, 5, 5, 4 ,3 ,2, 5, 5, 4, 5, 5};
		MajorityList ml = new MajorityList();
		
		System.out.println("输入数组为:");
		for (int i = 0; i < a.length; i++) {
			System.out.print(a[i]);
			System.out.print("  ");
			ml.add(a[i]);
		}
		System.out.println();
		
		boolean result = ml.hasMajorityElement();
		System.out.print("是否存在多数元素? ");
		System.out.println(result);
		if (result) {
			System.out.print("多数元素为:");
			System.out.println(ml.getMajorityElement());
		}
	}
}

 

 最后是Python实现:

 

#! /usr/bin/env python  
# -*- coding:utf-8 -*-

class MajorityList:
    def __init__(self):
        self._list = list()
        self.hasMajority = False
        self.majority_value = 0
        self._list.append(0)

    def candidate(self, m):
        j = m
        c = self._list[m]
        count = 1
        while j < len(self._list)-1 and count > 0:
            j = j + 1
            if self._list[j] == c:
                count += 1
            else:
                count -= 1
        if j == len(self._list)-1:
            return c
        else:
            return self.candidate(j+1)

    def majority(self):
        c = self.candidate(1)
        count = 0
        for j in range(1, len(self._list)):
            if self._list[j] == c:
                count += 1
        if count > (len(self._list)-1)/2:
            self.hasMajority = True
            self.majority_value = c
        else:
            self.hasMajority = False
            self.majority_value = 0
    
    def add(self, x):
        self._list.append(x)
        self.hasMajority = False
        self.majority_value = 0

    def hasMajorityElement(self):
        self.majority()
        return self.hasMajority

    def getMajorityElement(self):
        return self.majority_value

if __name__ == '__main__':
    a = [1, 2, 5, 5, 5, 4 ,3 ,2, 5, 5, 4, 5, 5]
    ml = MajorityList()

    print '输入数组为:'
    for i in a:
        print i,
        ml.add(i)
    print

    result = ml.hasMajorityElement()
    print '是否存在多数元素?', result
    if result:
        print '多数元素为:', ml.getMajorityElement()
 

 

分享到:
评论

相关推荐

    寻找多数元素的C++程序

    寻找多数元素的C++程序,可对任意长的数组,找出其中个数大于总个数一半的数字.

    算法设计技巧与分析寻找多数元素

    算法设计技巧与分析,寻找多数元素,包括工程、源码、说明文件、实验报告等文件

    算法MAJORITY(寻找多数元素)

    寻找多数元素。用递归算法MAJORITY实现多数的寻找,其中调用candidate(m)函数。

     算法设计大作业之寻找多数元素.doc

    算法设计大作业之寻找多数元素.doc

    利用归纳法寻找多数元素

    在数组中寻找次数多于数组长度一半的元素,即多数元素,采用归纳法将两个元素分为一组,不同相消,相同跳过。

    python简单程序编写.zip

    1018: 寻找多数元素 16 1022: csv 文件解析 17 1026: 键值查询 18 1027: 字符串相关操作2 19 1030: 集合的交 20 1028: 字符串相关操作3 21 1029: CSV 文件转换成 JSON 文件 21 1034: 列表实现筛选法求素数 23 1033: ...

    寻找主元素leetcode-LeetCode-Problems:LeetCode-问题

    多数元素 8. 最大连续数 9. 截留雨水 10. 第 N 个 Tribonacci 数 11. 最大冰淇淋棒 12. 排序颜色 13. 链表中间 14. 交换链表中的节点 15. 好的对数 16. 合并间隔 17. 随机字符串 18. 在二叉树的克隆中找到二叉树的...

    MajoritySearch.rar_数据结构_C/C++_

    C语言实现的寻找多数元素代码,含英文注释。算法采用《算法设计技巧与分析》(沙特)一书上的方法。

    ES6数组方法find()、findIndex()的总结

    本文主要讲解ES6数组方法find()与findIndex(),关于JS的更多数组方法,可参考以下: ①JavaScript 内置对象之-Array ②ES5新增数组方法(例:map()、indexOf()、filter()等) ③ES6新增字符串扩张方法includes()、...

    gasstationleetcode-leetcode:leetcode

    多数元素 ✓ 229 多数元素 II 274 H指数 275 H指数II 243 最短词距 244 最短词距 II 245 最短词距 III 217 包含重复 219 包含重复 II 220 包含重复 III 55 跳跃游戏 45 跳跃游戏二 121 买卖股票的最佳时机 122 买卖...

    leetcode296-Leetcode:这是我的leetcode存储库

    多数元素 考很少 229 多数元素 II 考很少 274 H指数 275 H指数II 二分查找 243 最短词距 244 最短词距 II 245 最短词距 III 217 包含重复 219 包含重复 II 考很少 220 包含重复 III 考很少 55 跳跃游戏 45 跳跃游戏...

    leetcode296-LeetCodeNotes:力码笔记

    多数元素 考很少- 229 多数元素 II 考很少- 274 H指数 + 275 H指数II 二分查找+ 243 最短词距 244 最短词距 II 245 最短词距 III 217 包含重复 + 219 包含重复 II 考很少+ 220 包含重复 III 考很少 55 跳跃游戏 45 ...

    鸡蛋掉落leetcode-LeetCode-Solutions:LeetCode-解决方案

    0169.多数元素 0188.买卖股票的最佳时机 IV 0240.搜索二维矩阵 II 0260.只出现一次的数字 III 0887.鸡蛋掉落 模拟 0134.加油站 0146.LRU缓存机制 0202.快乐数 0289.生命游戏 0371.两整数之和 0412.Fizz Buzz 数组 ...

    股票买卖最佳时机leetcode-Leetcode-Lintcode-Python:用Python解决leetcode&lintcode问题

    多数元素 (229) 多数元素 II (238) 除自身以外的数组的乘积 (243) 最短词距 (277) 找名人 (347) 前 K 个频繁元素 (349) 两个数组的交集 (442) 查找数组中的所有重复项 (605) 可以放置鲜花 (624) 数组中的最大距离 ...

    丢失的最小正整数leetcode-LeetCode:力码

    丢失的最小正整数leetcode ...多数元素 191 位1的个数 203 移除链表元素 206 反转链表 209 长度最小的子数组 215 数组中的第K个最大元素 217 存在重复元素 232 用栈实现队列 234 回文链表 237 删除

    LC_copy

    (169)多数元素 (229)多数派元素II (238)阵列除自身的乘积 (243)最短字距 (277)寻找名人 (347)前K个常用元素 (349)两个数组的交集 (442)查找数组中的所有重复项 (605)可以放花 (624)数组中的...

    leetcode卡-leetcode:leetcode

    多数元素_简单 2020-07-08 day6 存在重复元素_简单 2020-07-08 day7 存在重复元素ii_简单 2020-07-08 day8 存在重复元素iii_中等 2020-07-13 day9 寻找数组的中心索引_简单 2020-07-13 day10 长度最小的子数组_中等 ...

    leetcode双人赛-leetcode-go:leetcode-go

    多数元素 旋转数组 数组中的第K个最大元素 滑动窗口最大值 移动零 前 K 个高频元素 两个数组的交集 两个数组的交集 II 翻转对 数组的相对排序 剑指 Offer 40. 最小的k个数 面试题 08.03. 魔术索引

Global site tag (gtag.js) - Google Analytics