Magnitude Pole:数组中的一个元素,其左侧元素小于或等于它,右侧元素大于或等于它。
示例输入
3,1,4,5,9,7,6,11
所需的输出
4,5,11
我在面试中被问到这个问题,我必须返回元素的索引,只返回符合条件的第一个元素。
我的逻辑
- 取两个MultiSet(这样我们也可以考虑复制),一个用于元素的右侧,一个用于左侧的 元素(极点)。
- 从第0个元素开始,将所有元素放在“右边的集合”中。
- 如果第0个元素小于或等于“right set”上的所有元素,则返回基本条件,然后返回其索引。
- 否则将其放入“左侧集合”并从索引1处的元素开始。
- 遍历数组,每次从“左设置”中选择最大值,从“右设置”中选择最小值并进行比较。
- 在任何元素的任何时刻,左侧的所有值都在“左侧集合”中,右侧的值在“右侧集合”中
醇>
代码
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;
}
我的问题
- 我被告知我的逻辑不正确,我无法理解为什么这个逻辑是不正确的(虽然我检查了一些情况和 它正在返回正确的索引)
- 为了我自己的好奇心如何在O(n)时间内不使用任何set / multiset来做到这一点。
答案 0 :(得分:9)
对于O(n)算法:
你的代码(至少)错了:
if (A[i] > left_max && A[i] <= right_min) // <-- should be >= and <=
答案 1 :(得分:3)
O(N)在上面的每个步骤中,作为访问每个节点一次,所以O(N)整体。
答案 2 :(得分:3)
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;
}
答案 3 :(得分:1)
你的逻辑似乎完全正确(虽然没有检查实现),并且可以实现给出O(n)时间算法!很好的工作思维方式。
你的右集可以实现为支持min的堆栈,而左集可以实现为支持max的堆栈,这给出了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
答案 4 :(得分:1)
我在Codility上看到了这个问题,用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;
}
答案 5 :(得分:0)
以下代码怎么样?我认为在最坏的情况下效率并不好,但预计效率会很好。
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;
}
答案 6 :(得分:0)
mags
的int数组和名为maxMag
的int变量。maxMag
。maxMag = element
。结果:数组极数
答案 7 :(得分:0)
有趣的问题,我在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;
}