【數組】B079_LC_交換一次的先前排列(找最接近的升序數對)

一、Problem

給你一個正整數的數組 A(其中的元素不一定完全不同),請你返回可在 一次交換(交換兩數字 A[i] 和 A[j] 的位置)後得到的、按字典序排列小於 A 的最大可能排列。

如果無法這麼操作,就請返回原數組

輸入:[3,2,1]
輸出:[3,1,2]
解釋:
交換 2 和 1

輸入:[3,1,1,3]
輸出:[1,3,1,3]
解釋:
交換 1 和 3

二、Solution

方法一:規律

先交換位於後面的元素對字典序影響最小,所以從後往前找第一個升序對,將他們交換後返回,這是錯的,沒有那麼簡單…

比如這個樣例的答案就錯了

輸入:[3,1,1,3]
輸出:[1,1,3,3]
預期:[1,3,1,3]
class Solution {
    public int[] prevPermOpt1(int[] A) {
    	int n = A.length, ans[] = new int[n], min = -1;

    	for (int i = n-2; i >= 0; i--)
   		for (int j = n-1; j > i; j--) {
   			if (A[i] > A[j]) {
   				int t = A[i];
   				A[i] = A[j];
   				A[j] = t;
   			    return A;
   			}
   		}
    	return A;
    }
}

但出發點是對的,這是代碼寫錯了,上面找的升序數對不是挨地最近的,而交換最近的升序數對才能確保答案正確

class Solution {
    public int[] prevPermOpt1(int[] A) {
    	int n = A.length, ans[] = new int[n], min = -1;

    	for (int i = n-2; i >= 0; i--) if (A[i] > A[i+1]) {
            for (int j = n-1; j > i; j--) {
                if (A[i] > A[j] && A[j] != A[j-1]) {
                    int t = A[i];
                    A[i] = A[j];
                    A[j] = t;
                    return A;
                }
            }
        }
    	return A;
    }
}

複雜度分析

  • 時間複雜度:O(n2)O(n^2)
  • 空間複雜度:O(1)O(1)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章