Algorithm 访谈-在阵列中查找震级极点
震级极点:数组中的一个元素,其左侧元素小于或等于震级极点,而右侧元素大于或等于震级极点 示例输入Algorithm 访谈-在阵列中查找震级极点,algorithm,Algorithm,震级极点:数组中的一个元素,其左侧元素小于或等于震级极点,而右侧元素大于或等于震级极点 示例输入 3,1,4,5,9,7,6,11 4,5,11 所需输出 3,1,4,5,9,7,6,11 4,5,11 我在一次采访中被问到这个问题,我必须返回元素的索引,并且只返回满足条件的第一个元素 我的逻辑 取两个多重集(这样我们也可以考虑复制),一个用于元素的右手边,另一个用于左手边。 元素(极) 从第0个元素开始,将其余所有元素放在“右集合”中 基本条件如果第0个元素小于或等于“right se
3,1,4,5,9,7,6,11
4,5,11
所需输出
3,1,4,5,9,7,6,11
4,5,11
我在一次采访中被问到这个问题,我必须返回元素的索引,并且只返回满足条件的第一个元素
我的逻辑
int magnitudePole (const vector<int> &A) {
multiset<int> left, right;
int left_max, right_min;
int size = A.size();
for (int i = 1; i < size; ++i)
right.insert(A[i]);
right_min = *(right.begin());
if(A[0] <= right_min)
return 0;
left.insert(A[0]);
for (int i = 1; i < size; ++i) {
right.erase(right.find(A[i]));
left_max = *(--left.end());
if (right.size() > 0)
right_min = *(right.begin());
if (A[i] > left_max && A[i] <= right_min)
return i;
else
left.insert(A[i]);
}
return -1;
}
int震级极点(常数向量&A){
多集左,右;
int左最大值,右最小值;
int size=A.size();
对于(int i=1;ileft_max&&A[i]:
计算[0,长度(n))中所有k的n[0]到n[k]之间的最大元素,将答案保存在一个数组maxOnTheLeft中。这将花费O(n)
计算[0,length(n))中所有k的从n[k]到n[length(n)-1]的最小元素,将答案保存在数组minOnTheRight中。这将花费O(n)
在整个过程中循环,并用maxOnTheLeft
- 创造两个叫做北极和南极(只是为了幽默)
- 向前跨步通过迄今为止找到的[]跟踪最大元素,如果A[i]>Max(A[0..i-1]),则将SouthPole[i]设置为true
- 如果A[i]
- 向前跨过北极和南极,找到两个都设置为真的第一个元素
O(N)在上面的每个步骤中,就像访问每个节点一次一样,总体上也是O(N)。您的逻辑似乎完全正确(虽然没有检查实现),并且可以实现,以给出一个O(N)时间算法!从集合的角度考虑,做得很好
右边的集合可以实现为一个支持最小值的堆栈,左边的集合可以实现为一个支持最大值的堆栈,这给出了一个O(n)时间算法
拥有一个支持max/min的堆栈是一个众所周知的面试问题,并且可以在每个操作(push/pop/min/max是O(1))中进行
要将其用于逻辑,伪代码将如下所示
foreach elem in a[n-1 to 0]
right_set.push(elem)
while (right_set.has_elements()) {
candidate = right_set.pop();
if (left_set.has_elements() && left_set.max() <= candidate <= right_set.min()) {
break;
} else if (!left.has_elements() && candidate <= right_set.min() {
break;
}
left_set.push(candidate);
}
return candidate
[n-1到0]中的每个元素
右推(elem)
while(右\u集。有\u元素(){
候选=右_set.pop();
如果(left_set.has_elements()&&left_set.max()那么下面的代码呢?我认为在最坏的情况下它的效率并不好,但它的预期效率会很好
int getFirstPole(int* a, int n)
{
int leftPole = a[0];
for(int i = 1; i < n; i++)
{
if(a[j] >= leftPole)
{
int j = i;
for(; j < n; j++)
{
if(a[j] < a[i])
{
i = j+1; //jump the elements between i and j
break;
}
else if (a[j] > a[i])
leftPole = a[j];
}
if(j == n) // if no one is less than a[i] then return i
return i;
}
}
return 0;
}
int-getFirstPole(int*a,int-n)
{
int leftPole=a[0];
对于(int i=1;i=leftPole)
{
int j=i;
对于(;ja[i])
leftPole=a[j];
}
如果(j==n)//如果没有人小于a[i],则返回i
返回i;
}
}
返回0;
}
创建名为mags
的整数数组和名为maxMag
的整数变量
对于源数组中的每个元素,检查元素是否大于或等于maxMag
如果是:将元素添加到mags数组并设置maxMag=element
如果不是:循环通过mags阵列并移除所有元素
结果:数量级极点数组我在Codibility上看到了这个问题,用Perl解决了它:
sub solution {
my (@A) = @_;
my ($max, $min) = ($A[0], $A[-1]);
my %candidates;
for my $i (0..$#A) {
if ($A[$i] >= $max) {
$max = $A[$i];
$candidates{$i}++;
}
}
for my $i (reverse 0..$#A) {
if ($A[$i] <= $min) {
$min = $A[$i];
return $i if $candidates{$i};
}
}
return -1;
}
子解决方案{
我的(@A)=;
我的($max,$min)=($A[0],$A[-1]);
我的%候选人;
我的$i(0..$#A){
如果($A[$i]>=$max){
$max=$A[$i];
$candidates{$i}++;
}
}
对于我的$i(反向0..$#A){
如果($A[$i]Java实现:
Collection<Integer> magnitudes(int[] A) {
int length = A.length;
// what's the maximum number from the beginning of the array till the current position
int[] maxes = new int[A.length];
// what's the minimum number from the current position till the end of the array
int[] mins = new int[A.length];
// build mins
int min = mins[length - 1] = A[length - 1];
for (int i = length - 2; i >= 0; i--) {
if (A[i] < min) {
min = A[i];
}
mins[i] = min;
}
// build maxes
int max = maxes[0] = A[0];
for (int i = 1; i < length; i++) {
if (A[i] > max) {
max = A[i];
}
maxes[i] = max;
}
Collection<Integer> result = new ArrayList<>();
// use them to find the magnitudes if any exists
for (int i = 0; i < length; i++) {
if (A[i] >= maxes[i] && A[i] <= mins[i]) {
// return here if first one only is needed
result.add(A[i]);
}
}
return result;
}
收集量级(int[]A){
int length=A.length;
//从数组开始到当前位置的最大数目是多少
int[]maxes=新的int[A.length];
//从当前位置到数组末尾的最小数目是多少
int[]分钟=新的int[A.长度];
//建造分钟
int min=min[length-1]=A[length-1];
对于(int i=length-2;i>=0;i--){
if(A[i]max){
max=A[i];
}
最大值[i]=最大值;
}
收集结果=新建ArrayList();
//如果存在震级,则使用它们来查找震级
for(int i=0;i 如果(A[i]>=maxes[i]&&A[i]是一个有趣的问题,我有我自己的C#解决方案,我在下面给出了,请阅读评论以了解我的方法
public int MagnitudePoleFinder(int[] A)
{
//Create a variable to store Maximum Valued Item i.e. maxOfUp
int maxOfUp = A[0];
//if list has only one value return this value
if (A.Length <= 1) return A[0];
//create a collection for all candidates for magnitude pole that will be found in the iteration
var magnitudeCandidates = new List<KeyValuePair<int, int>>();
//add the first element as first candidate
var a = A[0];
magnitudeCandidates.Add(new KeyValuePair<int, int>(0, a));
//lets iterate
for (int i = 1; i < A.Length; i++)
{
a = A[i];
//if this item is maximum or equal to all above items ( maxofUp will hold max value of all the above items)
if (a >= maxOfUp)
{
//add it to candidate list
magnitudeCandidates.Add(new KeyValuePair<int, int>(i, a));
maxOfUp = a;
}
else
{
//remote all the candidates having greater values to this item
magnitudeCandidates = magnitudeCandidates.Except(magnitudeCandidates.Where(c => c.Value > a)).ToList();
}
}
//if no candidate return -1
if (magnitudeCandidates.Count == 0) return -1;
else
//return value of first candidate
return magnitudeCandidates.First().Key;
}
public int magnityPoleFinder(int[]A)
{
//创建一个变量来存储最大值项,即maxOfUp
int maxOfUp=A[0];
//如果列表只有一个值,则返回此值
如果(A.长度=ma