使用分而治之算法的多数元素

时间:2016-04-22 12:30:24

标签: python algorithm sorting

大家好! 长度为n的序列的元素如果在序列中出现的次数严格超过n / 2次,则称为多数元素。

此代码问题的目标是检查输入序列是否包含多数元素。

我正在尝试使用合并排序算法来解决这个问题

我的策略:

  1. 使用合并算法对序列进行排序

  2. 在排序列表中查找每个元素的出现位置。如果它超过n / 2,则返回1.由于列表已排序,我想查看列表,如果下一个元素与前一个元素不同,则计数器停止并将其与n / 2进行比较

    def merge(left,rigt):
        result = []
        i = j = 0
        while i < len(left) and j < len(rigt):
            if left[i] <= rigt[j]:
                result.append(left[i])
                i += 1
    
            else:
                result.append(rigt[j])
                j += 1
    
        result += left[i:]
        result += rigt[j:]
    
        return result
    
    def merge_sort(a):
    if len(a) <= 1:
        return a
    
    middle = len(a)//2
    
    left = a[:middle]
    right = a[middle:]
    
    left = merge_sort(left)
    right = merge_sort(right)
    
    return list(merge(left,right))
    
    def get_major_element(a,n):
    
    k = 1
    
    for i in range(0,len(a)-1):
        if a[i] == a[i+1]:
            k += 1
    
    if k > n/2:
        return 1
    
    else:
        return 0
    
    if __name__ == '__main__':
        input = sys.stdin.read()
        data = list(map(int, input.split()))
        n = data[0]
        a = data[1:]
        m = merge_sort(a)
        print (get_major_element(m,n))
    
  3. 我得到的结果无效。 我想,我可以在没有初始排序的情况下做到这一点,但是我不知道应该重写哪一步!有人可以帮忙吗?

7 个答案:

答案 0 :(得分:0)

我会创建一组唯一元素并在原始列表中计算它们的出现次数,然后将最大值与列表长度进行比较:

def get_major_element(my_list):
    available_items = set(my_list)
    max_count, max_item = max((my_list.count(item), item) for item in available_items)
    return max_item if max_count > len(my_list)/2 else None

See this code running on ideone.com

答案 1 :(得分:0)

如果有一个原因是你没有使用其他人指出的内置排序和计数机制,那么这将在一次通过中完成,而不使用任何非常基本的数据类型。许多内置操作可能包含在最坏的情况下可能使它们成为O(n ** 2)的循环。

def getMajor(L):
    best = None
    elements = {}
    for element in L:
        elements[element] += 1
        if elements[element] > elements.get(best, 0):
            best = element

    if elements.get(best, 0) > len(L)/2:
        return best, elements.get(best, 0)
    else:
        return None, 0

答案 2 :(得分:0)

检查摩尔算法,它在两次通过中工作并在O(N)中找到多数元素

或者简单地排序中间索引上的数组和元素(startIndex + endIndex)/ 2应该是多数元素。 (如果数组中有多数元素)。

答案 3 :(得分:0)

将阵列分成两半,左半部分和右半部分。请注意,如果一个元素是整个数组的大部分,那么它至少是其中一半的大部分。

因此,为了找到大部分数组,递归地找到两半的大部分,然后在数组上单次传递计算两个候选者出现在整个数组中的次数,以检查它们中的哪一个是整个阵列的大部分。

答案 4 :(得分:0)

它在java中适用于我

k=1;
for(c=0;c<n-1;c++){
    if(array[c]==array[c+1])
      k+=1;

    else k=0;


    if (k > n/2){
      System.out.print("1");
      break;

    }
  }
  if (k <=n/2){
      System.out.print("0");
}

答案 5 :(得分:0)

# Uses python3
import sys

def get_majority_element(a, left, right):
    if left == right:
        return -1
    if left + 1 == right:
        return a[left]


    left_elemt = get_majority_element(a,left,(left + right - 1) // 2 + 1)
    right_elemt = get_majority_element(a,(left + right - 1) // 2 + 1,right)

    l_count = 0
    for i in range(left,right):
        if a[i] == left_elemt:
            l_count += 1
    if l_count > (right - left)//2:
        return left_elemt

    rcount = 0
    for i in range(left, right):
        if a[i] == right_elemt:
            rcount += 1
    if rcount > (right - left) // 2:
        return right_elemt

    return -1


if __name__ == '__main__':
    input = sys.stdin.read()
    n, *a = list(map(int, input.split()))
    if get_majority_element(a, 0, n) != -1:
        print(1)
    else:
        print(0)

我花了很多时间在这上面。和你有同样的问题和困惑。看来Middle的功能应该是(left + right-1)// 2 +1(归功于mablatnik的git)(虽然我还不知道为什么)

答案 6 :(得分:-1)

https://stackoverflow.com/a/56161162/13467399

感谢您的帖子,伙计。我正在为这个问题挠头。我看到你想知道为什么作者通过 (left + right - 1) // (2 + 1) 找到中点。

这是因为这里的“正确”是取数组的大小,而数组总是从 0 开始而不是 1,这就是在除数中加 1 的答案。

其实中点可以用(left + right) / 2来计算。

抱歉,我没有权限,无法在您的帖子中发表评论。

相关问题