英文:
Find minimum peak elements in an array
问题
public int[] findMinimumPeaks(int[] arr){
List<Integer> list1 = new ArrayList<Integer>(arr.length);
int[] output = new int[arr.length];
for(int i: arr)
list1.add(i);
for(int i =0; i<arr.length; i++){
int minIndex = minimumPeakElement(list1);
output[i] = list1.get(minIndex);
list1.remove(minIndex);
}
return output;
}
public int minimumPeakElement(List<Integer> list1){
int minIndex = 0, peakStart = Integer.MAX_VALUE, peakEnd = Integer.MAX_VALUE;
int peak = Integer.MAX_VALUE, minPeak = Integer.MAX_VALUE;
if(list1.size() >= 2){
if(list1.get(0) > list1.get(1)) peakStart = list1.get(0);
if(list1.get(list1.size() - 1) > list1.get(list1.size() - 2)) peakEnd = list1.get(list1.size() - 1);
if(peakStart < peakEnd){
minPeak = peakStart;
minIndex = 0;
}
else if(peakEnd < peakStart){
minPeak = peakEnd;
minIndex = list1.size() - 1;
}
}
for(int i=1; i<list1.size() - 1; i++){
if(list1.get(i) > list1.get(i + 1) && list1.get(i) > list1.get(i-1)) peak = list1.get(i);
if(peak < minPeak){
minPeak = peak;
minIndex = i;
}
}
return minIndex;
}
Note: The code provided is the same as the original code you posted. I've only removed the HTML escape codes (e.g., <
and >
) for better readability. If you're looking for an optimized solution, I would recommend analyzing the algorithm and data structures used to see if there are any improvements that can be made.
英文:
Question: Given an array numbers = {2, 7, 8, 5, 1, 6, 3, 9, 4}
. Check the below conditions, both the conditions should be satisfied.
a[i] > a[i-1]
orif first element a[i] > a[i+1]
a[i] > a[i+1]
or iflast element a[lastelement] > a[lastelement - 1]
Therefore:
-
1st Iteration - 8, 6, 9 are peak values. Remove the smallest ele. Remove 6. New arr {2, 7, 8, 5, 1, 3, 9, 4}. Output Arr - {6}
-
2nd Iteration - 8, 9 are peak values. Remove the smallest ele. Remove 8. New arr {2, 7, 5, 1, 3, 9, 4}. Output Arr - {6, 8}
-
3rd Iteration - 7, 9 are peak values. Remove the smallest ele. Remove 7. New arr {2, 5, 1, 3, 9, 4}. Output Arr - {6, 7, 8}
-
4th Iteration - 5, 9 are peak values. Remove the smallest ele. Remove 5. New arr {2, 1, 3, 9, 4}. Output Arr - {6, 7, 8, 5}
-
5th Iteration - 2, 9 are peak values. Remove the smallest ele. Remove 2. New arr {1, 3, 9, 4}. Output Arr - {6, 7, 8, 5, 2}
-
6th Iteration - 9 are peak values. Remove the smallest ele. Remove 9. New arr {1, 3, 4}. Output Arr - {6, 7, 8, 5, 2, 9}
-
7th Iteration - 4 are peak values. Remove the smallest ele. Remove 4. New arr {1, 3}. Output Arr - {6, 7, 8, 5, 2, 9, 4}
-
8th Iteration - 3 are peak values. Remove the smallest ele. Remove 3. New arr {1}. Output Arr - {6, 7, 8, 5, 2, 9, 4, 3}
-
9th Iteration - 1 are peak values. Remove the smallest ele. Remove 1. New arr {1}. Output Arr - {6, 7, 8, 5, 2, 9, 4, 3, 1}
Output: {6, 8, 7, 5, 2, 9, 4, 3, 1}
My solution is working but I am looking for optimized solution. Please let me know.
Here is my code:
public int[] findMinimumPeaks(int[] arr){
List<Integer> list1 = new ArrayList<Integer>(arr.length);
int[] output = new int[arr.length];
for(int i: arr)
list1.add(i);
for(int i =0; i<arr.length; i++){
int minIndex = minimumPeakElement(list1);
output[i] = list1.get(minIndex);
list1.remove(minIndex);
}
return output;
}
public int minimumPeakElement(List<Integer> list1){
int minIndex = 0, peakStart = Integer.MAX_VALUE, peakEnd = Integer.MAX_VALUE;
int peak = Integer.MAX_VALUE, minPeak = Integer.MAX_VALUE;
if(list1.size() >= 2){
if(list1.get(0) > list1.get(1)) peakStart = list1.get(0);
if(list1.get(list1.size() - 1) > list1.get(list1.size() - 2)) peakEnd = list1.get(list1.size() - 1);
if(peakStart < peakEnd){
minPeak = peakStart;
minIndex = 0;
}
else if(peakEnd < peakStart){
minPeak = peakEnd;
minIndex = list1.size() - 1;
}
}
for(int i=1; i<list1.size() - 1; i++){
if(list1.get(i) > list1.get(i + 1) && list1.get(i) > list1.get(i-1)) peak = list1.get(i);
if(peak < minPeak){
minPeak = peak;
minIndex = i;
}
}
return minIndex;
}
答案1
得分: 1
以下是如何优化渐近复杂性的想法。
使用一次对初始数组的元素进行遍历,将其分割成“上升-下降”、“斜坡”或“山坡”,即升序排列的元素子序列,后跟降序排列的子序列。
将这些斜坡存储在以下数据结构中:
val slopes = MinPriorityQueue<Slope>()
class Slope(
var first: Int, // 斜坡的第一个元素
var last: Int, // 斜坡的最后一个元素
var peak: Int, // 最大或峰值元素
var els: MaxPriorityQueue<Int>(), // 斜坡的所有元素
var prev: Slope?, // 列表中前一个斜坡的链接,如果是第一个则为null
var next: Slope? // 列表中下一个斜坡的链接,如果是最后一个则为null
)
斜坡应该按照它们的peak
值进行比较。
现在,有了这个数据结构,您可以在O(log(N))
时间内poll
具有最小峰值的斜坡。在弹出斜坡后,您应该通过移除其峰值元素(即弹出els
,然后更新first
、last
、peak
)来更新斜坡,另外,斜坡可能有资格与前一个或下一个斜坡合并:
诚然,这个解决方案并不简单,需要维护很多内容和大量的边缘情况。然而,从渐近复杂性的角度来看,它要好得多。
- 初始数据结构构建:
O(n log(n))
- 在维护斜坡的同时进行元素轮询:
O(n log(n))
- 总体复杂性:
O(n log(n))
注:
-
其中一个边缘情况是,如果数组可以包含重复元素,那么内部优先级队列(
els
)将变为MaxPriorityQueue<Pair<Int, Int>>
,即您需要同时存储潜在的重复元素数量和元素值。 -
MinPriorityQueue
和MaxPriorityQueue
是一个基于堆的抽象数据结构,其中分别在头部具有最小和最大元素。可以在Java中使用PriorityQueue来实现。
英文:
Here is an idea how to optimize asymptotic complexity.
Use single pass over elements of your initial array to split it into "up-down" "slopes" or "hills", i.e. subsequence of elements in ascending order, followed by subsequence in descending order.
Store these slopes in the following datastructure:
val slopes = MinPriorityQueue<Slope>()
class Slope(
var first: Int, // first element of the slope
var last: Int, // last element of the slope
var peak: Int, // max or peak element
var els: MaxPriorityQueue<Int>(), // all elements of the slope
var prev: Slope?, // link to the previous slope in the list or null if first
var next: Slope? // link to the next slope in the list or null if last
)
Slopes should be comparable by their peak
value.
Now, having this data structure, you can poll
the slope that has minimal peak value in O(log(N))
. After you polled the slope, you should update the slope by removing it's peak element (i.e. poll els
, then update first
, last
, peak
), also, slope might become eligible to be merged with the previous or next slope:
Admittedly, this solution is not an easy one, having a lot of things to maintain and large number of corner cases. However, it's much better in terms of asymptotic complexity.
- Initial data structure build:
O(n log(n))
- Polling elements while maintaining slopes:
O(n log (n))
- Overall complexity:
O(n log(n))
Notes:
-
One of the corner cases, if array can have duplicate elements, then inner priority queue (
els
) becomesMaxPriorityQueue<Pair<Int,Int>>
, i.e. you need to store the number of potentially duplicate elements along with the element value. -
MinPriorityQueue
andMaxPriorityQueue
is an abstract heap-based data structure with min and max element at the head respectively. Can be implemented with PriorityQueue in java
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论