O(n) time
相当于找prev_permutation,要在右边找一个小数换左边的一个大数,右边的小数要在尾部的升序序列里找
312右侧升序,从后往前找到第一个违反升序的31,再在升序序列里找『第一个』比3小的最大的数,也就是先找3的下界再往前找第一次出现的最大的数跟3交换即可
1 2 3 4 5 6 7 8 9 10 11 12
| class Solution { public: vector<int> prevPermOpt1(vector<int>& A) { int n = size(A), i = n - 1; while (i > 0 && A[i - 1] <= A[i]) --i; if (i == 0) return A; int j = lower_bound(begin(A) + i, end(A), A[i - 1]) - begin(A) - 1; j = lower_bound(begin(A) + i, begin(A) + j + 1, A[j]) - begin(A); swap(A[i - 1], A[j]); return A; } };
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Solution { public: vector<int> prevPermOpt1(vector<int>& A) { int n = A.size(), x = n; for (int i = n - 2; i >= 0; --i) { if (A[i] > A[i + 1]) { x = i; break; } } if (x == n) return A; int y = lower_bound(begin(A) + x + 1, end(A), A[x]) - begin(A) - 1; y = lower_bound(begin(A) + x + 1, begin(A) + y + 1, A[y]) - begin(A); swap(A[x], A[y]); return A; } };
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class Solution { public: vector<int> prevPermOpt1(vector<int>& A) { int n = A.size(), x = n; for (int i = n - 2; i >= 0; --i) { if (A[i] > A[i + 1]) { x = i; break; } } if (x == n) return A; auto y = lower_bound(begin(A) + x + 1, end(A), A[x]) - begin(A) - 1; while (x < y && A[y - 1] == A[y]) { --y; } swap(A[x], A[y]); return A; } };
|