1. 程式人生 > >LeetCode-670:Maximum Swap (交換數字得最大整數) -- medium

LeetCode-670:Maximum Swap (交換數字得最大整數) -- medium

Question

Given a non-negative integer, you could swap two digits at most once to get the maximum valued number. Return the maximum valued number you could get.

Example 1:

Input: 2736
Output: 7236
Explanation: Swap the number 2 and the number 7.

Example 2:

Input: 9973
Output: 9973
Explanation: No swap.

Note:
* The given number is in the range [0, 108].

問題解析:

給定非空非負整數,最多交換其中的兩個數字,得到最大的整數,返回最大整數。

Answer

Solution 1:

個人解決方案:

  • 首先以例子分析要交換的特性,我們會發現,當整數中的所有數字均按照非遞增的順序排序,那麼這個整數就是最大整數,不需要進行交換;
  • 所以根據上面的分析,我們需要尋找整數中數字出現不符合非遞增規則的分裂點,記錄違規的分裂點;
  • 在分裂點的後半部分尋找最大的數字,並且位置越靠後的數字相對前面與其相等的前面的數字交換的意義更大,也就是我們要求尋找digits[j] >= max
    ,注意這裡是>=
  • 在分裂點的前半部分從後向前尋找小於上一步找到的max的最大值;
  • 將找到的兩個位置數字進行交換,即可得到交換最大整數。
  • 注意,為了進行操作,需先將整數轉化為char陣列,並在交換後轉換回整數。
class Solution {
    public int maximumSwap(int num) {
        char[] digits = Integer.toString(num).toCharArray();

        if(digits.length == 1) return num;

        // 尋找不符合非遞增順序的分界線
        int
split = 0; for (int i = 0; i < digits.length-1; i++){ if (digits[i] < digits[i+1]){ split = i+1; break; } } // 在分界線後面的部分尋找最大的值max char max = digits[split]; int index1 = split; for (int j = split+1; j < digits.length; j++){ if (digits[j] >= max){ max = digits[j]; index1 = j; } } // 在分界線前面的部分向前尋找小於max的最大值 int index2 = split; for (int i = split-1; i >= 0; i--){ if (digits[i] >= max){ break; } index2--; } //交換兩位找到的char char temp = digits[index1]; digits[index1] = digits[index2]; digits[index2] = temp; return Integer.valueOf(new String(digits)); } }
  • 時間複雜度:O(n),空間複雜度:O(n)

Solution 2:

利用桶的思想。

  • 利用indices桶陣列記錄數字0〜9的最後位置。
  • 遍歷整個整數變為char的陣列,從左到右提取每一個數字;
  • 對提取到的每一個數字檢查是否存在比它更大的數字存在,故與桶的位置數字做比較(從9開始到當前數字);
  • 如果,存在比提取的數字更大的桶,我們還需要確保這個較大數字的位置落後於桶數字所在的位置;
  • 如果找到,則交換兩個位置,轉換陣列並返回。
  • 這種解法更加巧妙。
class Solution {
    public int maximumSwap(int num) {
        char[] digits = Integer.toString(num).toCharArray();
        int[] indices = new int[10];
        int result = num;
        for(int i = 0; i < digits.length; i++) {
            indices[digits[i] - '0'] = i;
        }
        for(int i = 0; i < digits.length-1; i++) {
            int digit = digits[i] - '0';
            for(int j = 9; j > digit; j--) {
                if(indices[j] > i) {
                    char temp = digits[i];
                    digits[i] = digits[indices[j]];
                    digits[indices[j]] = temp;
                    result = Integer.parseInt(new String(digits));
                    return result;
                }
            }
        }
        return result;
    }
}
  • 時間複雜度:O(n),空間複雜度:O(n)