Python 使用分治算法的多数元素
各位!! 如果长度为n的序列中的元素严格地出现在序列中超过n/2倍,则称为多数元素 此代码问题的目标是检查输入序列是否包含多数元素 我试图用合并排序算法来解决这个问题 我的策略:Python 使用分治算法的多数元素,python,algorithm,sorting,Python,Algorithm,Sorting,各位!! 如果长度为n的序列中的元素严格地出现在序列中超过n/2倍,则称为多数元素 此代码问题的目标是检查输入序列是否包含多数元素 我试图用合并排序算法来解决这个问题 我的策略: 排序序列,使用合并算法 查找排序列表中每个元素的匹配项。如果大于n/2,则返回1。当列表被排序时,我想遍历列表,如果下一个元素不同于前一个元素,计数器停止并将其与n/2进行比较 def merge(left,rigt): result = [] i = j = 0 while i < le
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))
def合并(左,右):
结果=[]
i=j=0
而i 如果左[i]我将创建一组唯一的元素,并计算它们在原始列表中的出现次数,然后将最大值与列表长度进行比较:
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
如果您不使用其他人指出的内置排序和计数机制是有原因的,那么这将在一次传递中完成,而只使用非常基本的数据类型。许多内置操作可能包含循环,在最坏的情况下可能使它们成为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
检查摩尔算法,它在两个过程中工作,并在O(N)中找到多数元素
或者简单地对数组进行排序,中间索引上的元素(startIndex+endIndex)/2应该是多数元素。(如果数组中有多数元素)。将数组分为左右两半。请注意,如果一个元素是整个数组的多数,那么它至少是其中一个半数组的多数
因此,要找到一个数组的大部分,递归地找到两个半数组的大部分,然后通过对数组的一次遍历来计算两个候选数组在整个数组中出现的次数,以检查其中哪一个是整个数组的大部分。这在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");
}
k=1;
对于(c=0;c n/2){
系统输出打印(“1”);
打破
}
}
if(k)
我花了很多时间在这个问题上。我和你有同样的问题和困惑。看起来中间的函数应该是(左+右-1)//2+1(归功于mablatnik的git)(尽管我还不知道为什么)
谢谢你的帖子,伙计。我对这个问题有些挠头。我看到你在想为什么作者通过(左+右-1)/(2+1)找到了中点
这是因为这里的“右”表示数组的大小,数组总是从0开始,而不是从1开始,这就需要在除数中加1
实际上,可以使用(左+右)/2计算中点
很抱歉,我不能在你的帖子中发表评论,因为我没有特权。你没有使用排序
或列表的任何特殊原因。排序
?我想这是一项作业。如果作业是关于排序的,你应该在问题中说明(这样我们就不会提出不同的方法);如果不是关于排序,而您只是使用排序来解决问题,那么只需使用bultin排序函数。此外,您是否尝试过使用collections.Counter(列表)。最常见的(1)
?有一种众所周知的标准算法,可以通过对数组和O(1)进行单次遍历来解决此问题空间。这是我首先想到的,但这将是一个有效的解决方案。我需要在这里实现分治算法。分治算法是什么?如果你能解释一下,让我们知道你想要什么,那将非常有用。@ByteCommander a“分治”算法是一种可以递归地将问题分解成更小的子问题,直到每个子问题都有一个简单的案例,并将它们组合成一个全局解决方案的算法。问题是关于Python的,您的代码假设数组是排序的,这在问题中没有说明。这不是问题的答案,而是请注意括号,因为在此上下文中,(2+1)
是不正确的,因为运算符优先级在他们的答案中是正确的。对不起,我不能在他的帖子中发表评论,因为我没有足够的特权点数。谢谢你指出我在回答中的错误。
# 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)