数组中大小为k的最小词典子序列

时间:2016-03-01 03:14:57

标签: arrays dynamic-programming greedy

给定一个整数数组,找到大小为k的最小的词法子序列。 EX: Array : [3,1,5,3,5,9,2] k =4 Expected Soultion : 1 3 5 2

6 个答案:

答案 0 :(得分:2)

这是一个应该有效的greedy算法:

Choose Next Number ( lastChoosenIndex, k ) {

    minNum = Find out what is the smallest number from lastChoosenIndex to ArraySize-k

    //Now we know this number is the best possible candidate to be the next number.
    lastChoosenIndex = earliest possible occurance of minNum after lastChoosenIndex

    //do the same process for k-1
    Choose Next Number ( lastChoosenIndex, k-1 )
}

上面的算法很复杂。

但是我们pre-sort可以使用paired array index所有数组元素n*log(n),并使用单个循环贪婪地执行相同的过程。 由于我们使用排序复杂性仍然是function EventListenerForPopUp() { this.removeEventListener("animationend", EventListenerForPopUp ); this.Show.resolve(); } function ShowHideDiv() { this.Show = function () { return new Promise(function(resolve, reject) { this.Div.addEventListener("animationend", EventListenerForPopUp, false); }.bind(this)); } }

答案 1 :(得分:0)

  1. 我建议您尝试使用修改后的合并排序。
  2. 的地方
  3. 修改为合并部分,丢弃重复值。
  4. 选择最小的四个
  5. 复杂性为o(n logn) 仍在思考复杂性是否可以是o(n)

答案 2 :(得分:0)

如果我对问题的理解正确,那么这里的DP算法应该可以工作,但是需要O(NK) time

//k is the given size and n is the size of the array
create an array dp[k+1][n+1]

initialize the first column with the maximum integer value (we'll need it later)
and the first row with 0's (keep element dp[0][0] = 0)

now run the loop while building the solution 

for(int i=1; i<=k; i++) {
  for(int j=1; j<=n; j++) {
      //if the number of elements in the array is less than the size required (K) 
      //initialize it with the maximum integer value
      if( j < i ) {
          dp[i][j] = MAX_INT_VALUE;
      }else {
          //last minimum of size k-1 with present element or last minimum of size k
          dp[i][j] = minimun (dp[i-1][j-1] + arr[j-1], dp[i][j-1]);
      } 
   }
}
//it consists the solution
return dp[k][n];

数组的最后一个元素包含解决方案。

答案 3 :(得分:0)

可以通过维护双端队列(双端队列)在O(n)中解决该问题。我们从左到右迭代元素,并确保双端队列始终保持最小的词典顺序。仅当当前元素小于deque中的元素并且deque中的总元素加上剩余待处理的元素至少为k时,才应弹出元素。

vector<int> smallestLexo(vector<int> s, int k) {
    deque<int> dq;
    for(int i = 0; i < s.size(); i++) {
        while(!dq.empty() && s[i] < dq.back() && (dq.size() + (s.size() - i - 1)) >= k) {
            dq.pop_back();
        }
        dq.push_back(s[i]);
    }
    return vector<int> (dq.begin(), dq.end());
}

答案 4 :(得分:0)

Ankit Joshi的答案有效。但是我认为可以仅通过向量本身来完成操作,而不必使用双端队列,因为完成的所有操作也可以在向量中进行。同样在Ankit Joshi的答案中,双端队列可能包含其他元素,我们必须在返回之前手动弹出这些元素。返回之前添加这些行。

while(dq.size() > k)
{
       dq.pop_back();
}

答案 5 :(得分:0)

可以用O(n)+ Klog(n)中的RMQ来完成。 在O(n)中构造一个RMQ。 现在找到每个第i th 元素最小的序列。从pos [x (i-1) +1到n-(Ki)](对于i [1到K],其中x 0 = 0,x i 是给定数组中第i个 最小元素的位置)