寻找多数元素

今天实现的算法是寻找多数元素,多数元素是指在一个含有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()
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值