【问题标题】:Find the index of the closest number that is greater than the current number查找大于当前数字的最接近数字的索引
【发布时间】:2020-07-12 03:07:05
【问题描述】:

对于正整数数组中的每个整数,找到比当前整数大的最接近整数的索引。另外,我们只需要在当前整数的左边寻找答案。

例如-

Input array - [ 5, 4, 3, 6, 2, 3]
Output array - [ -1, 0, 1, -1, 3, 3]

将 -1 分配给那些没有答案的数字。

有一个简单的 O(n^2) 方法,对每个数字运行一个从前一个数字到数组开头的 for 循环。

for(int i=0; i<n; ++i)
{
    output[i] = -1;
    for(int j=i-1; j>=0; --j)
    {
        if(input[j] > input[i])
        {
            output[i] = j;
            break;
        }
    }
}

当 'n' 很大时,此方法效率低下。有没有更有效的方法?

【问题讨论】:

  • 您可以使用已经建立的链接。对于每个元素x,向左看一个。如果那个大于x,链接到它。否则,它是一个链表的头部,形成一个不断增加的序列 - 跟随它,直到找到一个大于 x 的数字,或者到达末尾。我认为这个算法是O(n),但看不到一个简单的证明。

标签: c++ algorithm


【解决方案1】:

我相信一个流行的O(n) 解决方案是使用堆栈,保持降序(希望算法从注释代码中足够清楚):

function f(A){
  let stack = []
  let output = []

  for (let i=0; i<A.length; i++){
    // While there are lower or
    // equal elements on top of
    // the stack
    while (stack.length && A[ stack[stack.length-1] ] <= A[i])
      stack.pop();
    
    // The next greater element
    // to the left
    if (stack.length)
      output.push(stack[stack.length-1]);
    // There was none
    else
      output.push(-1);

    stack.push(i);
  }

  return output;
}

var As = [
  [5, 4, 3, 6, 2, 3],
  [1, 2, 3, 4, 5],
  [5, 4, 3, 2, 1],
  [0, 3, -1, 5, 4]
];

for (let A of As){
  console.log(`${ A }`);
  console.log(`${ f(A) }`);
  console.log('');
}

【讨论】:

    【解决方案2】:

    建议的答案是:https://www.geeksforgeeks.org/find-the-nearest-smaller-numbers-on-left-side-in-an-array/

    主要思想是使用堆栈来记住处理后的值。在链接中,他们关心值,但它可以很容易地适应输出索引。

    #include <iostream>
    #include <vector>
    #include <stack>
    
    std::vector<int> function(std::vector<int> input) {
        std::vector<int> output;
        output.reserve(input.size());
    
        // Create an empty stack 
        // first element of the pair is the index. second is the value
        std::stack<std::pair<int,int>> S; 
      
        // Traverse all array elements 
        for (int i=0; i<input.size(); i++) 
        { 
            // Keep removing top element from S while the top 
            // element is less than or equal to arr[i] 
            while (!S.empty() && S.top().second <= input[i]) 
                S.pop(); 
      
            // If all elements in S were greater than arr[i] 
            if (S.empty()) 
                output.push_back(-1);
            else  //Else print the nearest smaller element
                output.push_back(S.top().first);
    
      
            // Push this element 
            S.push({i, input[i]}); 
        } 
        
        return output;
    }
    
    int main() {
        std::vector<int> input{5, 4, 3, 6, 2, 3};
        std::vector<int> output = function(input);
    
        for(int index : output) {
            std::cout << index << ' ';
        }
    
        return 0;
    }
    

    输出:

    -1 0 1 -1 3 3
    

    编译器资源管理器:https://godbolt.org/z/8W3ecv

    【讨论】:

      猜你喜欢
      • 2015-04-18
      • 2016-08-05
      • 1970-01-01
      • 2022-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-05
      相关资源
      最近更新 更多