大家好! 长度为n的序列的元素如果在序列中出现的次数严格超过n / 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))
我得到的结果无效。 我想,我可以在没有初始排序的情况下做到这一点,但是我不知道应该重写哪一步!有人可以帮忙吗?
答案 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
答案 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来计算。
抱歉,我没有权限,无法在您的帖子中发表评论。