zoukankan      html  css  js  c++  java
  • [微软][笔试] 找出最大序列对

    对于一个数组,找出这样一个序列对(i, j),满足A[i] < A[j],且使 j - i的值最大,输出j - i的值。

    这道题最初想到的是O(n^2)的解答,后来想到了用MergeSort时来记录最大序列对的方法,也可以用一个队列来做。总之解法还挺多。

    最后和http://ac.jobdu.com/problem.php?cid=1039&pid=19何海涛的这题非常相似。

    方法1:MergeSort,数组的元素需要记录原始的元素索引。

     1 #include <iostream>
     2 using namespace std;
     3 
     4 struct Node
     5 {
     6     int val;
     7     int index;
     8 };
     9 Node b[1000];
    10 
    11 int mergeSort(Node a[], int left, int right)
    12 {
    13     if (left > right)
    14         return -1;
    15 
    16     if (left == right)
    17         return 0;
    18 
    19     int mid = left + (right - left) / 2;
    20 
    21     int leftRes = mergeSort(a, left, mid);
    22     int rightRes = mergeSort(a, mid + 1, right);
    23 
    24     int res = max(leftRes, rightRes);
    25 
    26     int i = left;
    27     int j = mid + 1;
    28     int minIndex = INT_MAX;
    29     int index = i;
    30 
    31     while(i <= mid && j <= right)
    32     {
    33         if (a[i].val <= a[j].val)
    34             b[index] = a[i++];
    35         else
    36             b[index] = a[j++];
    37 
    38         if (minIndex != INT_MAX)
    39             res = max(b[index].index - minIndex, res);
    40 
    41         minIndex = min(b[index].index, minIndex);
    42 
    43         index++;
    44     }
    45 
    46     while(i <= mid)
    47     {
    48         b[index] = a[i++];
    49 
    50         if (minIndex != INT_MAX)
    51             res = max(b[index].index - minIndex, res);
    52 
    53         minIndex = min(b[index].index, minIndex);
    54 
    55         index++;
    56     }
    57 
    58     while(j <= right)
    59     {
    60         b[index] = a[j++];
    61 
    62         if (minIndex != INT_MAX)
    63             res = max(b[index].index - minIndex, res);
    64 
    65         minIndex = min(b[index].index, minIndex);
    66 
    67         index++;
    68     }
    69 
    70     return res;
    71 }
    72 
    73 int main()
    74 {
    75     int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    76 
    77     int aSize = sizeof(a) / sizeof(int);
    78 
    79     Node *c = new Node[aSize];
    80 
    81     for(int i = 0; i < aSize; i++)
    82     {
    83         c[i].val = a[i];
    84         c[i].index = i;
    85     }
    86 
    87     cout << mergeSort(c, 0, aSize - 1) << endl;
    88 }

    方法2:用一个队列保存递减序列,从数组的第一个数开始,不断放入,当当前数小于队列的尾元素则放入。这样就构成了一个递减序列。当有新元素时查找队列中第一个小于新元素的数,然后就能得出一个j-i的值,如此就能得出解。由于队列有序,所以用二分查找的变形O(logn)。最后总的复杂度O(nlogn)

     1 #include <iostream>
     2 #include <vector>
     3 using namespace std;
     4 
     5 struct Node
     6 {
     7     int index;
     8     int val;
     9     Node(){}
    10     Node(int idx, int v):index(idx), val(v){}
    11 };
    12 
    13 int findIndex(vector<Node> &a, int left, int right, int key)
    14 {
    15     if (left > right)
    16         return -1;
    17 
    18     int mid = left + (right - left) / 2;
    19 
    20     if (a[mid].val < key)
    21     {
    22         int index = findIndex(a, left, mid - 1, key);
    23         return (index == -1 ? a[mid].index : index);
    24     }
    25     else
    26     {
    27         return findIndex(a, mid + 1, right, key);
    28     }
    29 }
    30 
    31 int solve(int a[], int aSize)
    32 {
    33     if (aSize == 0)
    34         return 0;
    35 
    36     vector<Node> q;
    37 
    38     int res = 0;
    39     for(int i = 0; i < aSize; i++)
    40     {
    41         if (q.size() == 0)
    42             q.push_back(Node(i, a[i]));
    43         else if (q[q.size() - 1].val > a[i])
    44             q.push_back(Node(i, a[i]));
    45 
    46         int index = findIndex(q, 0, q.size() - 1, a[i]);
    47 
    48         if (index != -1)
    49             res = max(res, i - index);
    50     }
    51 
    52     return res;
    53 }
    54 
    55 int main()
    56 {
    57     int a[] = {9, 8, 7, 6, 5, 4, 3, 2, 9};
    58     int aSize = sizeof(a) / sizeof(int);
    59     cout << solve(a, aSize) << endl;
    60 
    61     int b[] = {1, 2, 3};
    62     int bSize = sizeof(b) / sizeof(int);
    63     cout << solve(b, bSize) << endl;
    64 
    65     int c[] = {3, 2, 1};
    66     int cSize = sizeof(c) / sizeof(int);
    67     cout << solve(c, cSize) << endl;
    68 }
  • 相关阅读:
    蓝桥杯 勾股数 暴力
    蓝桥杯 连接乘积 暴力
    蓝桥杯 师座操作系统 map
    蓝桥杯 洗牌 vector
    蓝桥杯 盾神与砝码称重 dfs 剪枝
    蓝桥杯 盾神与积木游戏 贪心
    RESTful风格API
    APIview使用
    linux常用命令
    python中的三种路径
  • 原文地址:https://www.cnblogs.com/chkkch/p/2759579.html
Copyright © 2011-2022 走看看