对于具有单峰值元素的数组,可以使用二进制搜索在o(logn)中完成,但是如果数组中有多个峰值元素,我们应该使用哪种方法?
---提供更多信息---- 峰值元素比其邻居更大,例如,查看下面的数组,
[1,3,20,4,1,0,7,5,2]
其中有2个峰,20和7.
我们需要设计一种算法来查找此数组中的峰值元素。
答案 0 :(得分:0)
我可能无法理解你的问题,因为找到单个峰值可以在O(logn)中完成,需要在第一个位置对数组进行排序。
我建议你存储一个差异数组,它会生成如下输出:[1,3,20,4,1,0,7,5,2]
=> [1, 1,-1,-1,-1, 1,-1,-1]
只是生成一个大小为n - 1
的数组,并将增加的方向放在数组中。这可以在O(n)单次通过中完成。
在第二遍中,您将寻找[1,-1]对,这是发生峰值的地方。
如果要在开头和结尾找到峰值,则需要检查start是否为-1,结束为1。
希望这有帮助。
答案 1 :(得分:0)
我们的想法是使用修改后的二进制搜索。
如果s -> [a], a
s -> [c], c
a -> [a], a
a -> [b], b
a -> [c], c
b -> [b]
b -> [b], b
b -> [a], a
b -> [c], c
c -> [c], c
c -> [a], a
c -> [b], b
,则您的高峰总是存在于右半部分。
如果arr[mid+1]>arr[mid]
,则左半部分始终存在峰值。
因为arr [i + 1]只有两个选项,要么大于arr [i]要么小于arr [i-1]
我没有java实现,但这是一个python实现。
arr[mid-1]>arr[mid]
答案 2 :(得分:0)
用于查找具有多个峰的所有峰元素。
class Solution(object):
def findPeakElement(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
left, right = 0, len(nums) - 1
while left < right:
mid = left + right >> 1
if nums[mid] < nums[mid + 1]:
left = mid + 1
else:
right = mid
return left
答案 3 :(得分:0)
我最近在一个编程网站上遇到了类似的问题,但是除了发现峰值以外,还有另一个重要的限制。首先,可能有多个高峰,但也可能有高原!平稳是在arr中发生的事情:[1,2,2,2,1],在这种情况下,我们必须将峰返回为2。在问题中,我们还被要求返回峰的第一个位置发生,所以在这种情况下,它将是position =1。唯一需要注意的是arr:[1,2,2,2,3,4,5,1]中存在峰值在倒数第二个位置中有5个,但即使有一系列重复项在第一眼看上去都像高原一样,也没有高原。
所以我想到的基本算法是使用差异数组,正如使用{1,0,-1}所建议的那样,当在连续流中获得一系列重复项时,我们使用0。每当在检查差值数组时获得0时,我们就会开始寻找第一个非零条目(无论是1还是-1)并相应地输出。但是,我们再次要保持谨慎,可能是差分数组看起来像Diff = [-1,1,-1,1,0,0,0],在这种情况下没有平台,只有一个峰。当输入为arr时,python代码如下所示:
n = len(arr)
if arr == []:
return {"pos":[],"peaks":[]}
Diff = []
for i in range(0,n-1):
if arr[i]< arr[i+1]:
Diff.append(1)
elif arr[i] == arr[i+1]:
Diff.append(0)
if arr[i] > arr[i+1]:
Diff.append(-1)
pos = []
peaks = []
j = 0
for i in range(0,n-2):
if Diff[i] == 1 and Diff[i+1] == -1:
pos.append(i+1)
peaks.append(arr[i+1])
if Diff[i] == 1 and Diff[i+1] == 0:
if Diff[i+1:] == [Diff[i+1]]:
break
j = i+1
while(Diff[j] == 0 and j < n-2):
j = j+1
if Diff[j] == -1:
pos.append(i+1)
peaks.append(arr[i+1])
return {"pos":pos, "peaks":peaks}
答案 4 :(得分:0)
int arr[] = {50, 12, 13, 20, 16, 19, 11, 7, 24};
int size = sizeof(arr) / sizeof(arr[0]);
int peak_arr[size / 2];
int i, j, k = 0;
int next, previous = 0;
for(i = 0; i < size; i++){
if(i + 1 == size){
next = 0;
}
else{
next = arr[i + 1];
}
if(arr[i] > next && arr[i] >= previous){
peak_arr[k++] = arr[i];
}
previous = arr[i];
}
答案 5 :(得分:-1)
使用递归方法查找多个峰值元素。
def Div(lst, low, high):
mid = (low + high)//2
if low > high:
return ""
else:
if mid+1 < len(lst) and lst[mid] > lst[mid+1] and lst[mid] > lst[mid -1]:
return str(lst[mid]) + " " + Div(lst, low, mid-1) + Div(lst, mid+1, high)
else:
return Div(lst, low, mid-1) + Div(lst, mid + 1, high)
def peak(lst):
if lst == []:
return "list is empty"
elif len(lst) in [1, 2]:
return "No peak"
else:
return Div(lst, 0, len(lst))
print(peak([0, 5, 2, 9, 1, 10, 1]))