數(shù)組,找規(guī)律


下一個(gè)排列(https://leetcode-cn.com/problems/next-permutation/)

實(shí)現(xiàn)獲取下一個(gè)排列的函數(shù),算法需要將給定數(shù)字序列重新排列成字典序中下一個(gè)更大的排列。
如果不存在下一個(gè)更大的排列,則將數(shù)字重新排列成最小的排列(即升序排列)。
必須原地修改,只允許使用額外常數(shù)空間。
以下是一些例子,輸入位于左側(cè)列,其相應(yīng)輸出位于右側(cè)列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

找規(guī)律
對(duì)于任何題目,可以找一個(gè)簡(jiǎn)單的例子,然后手動(dòng)列舉出所有的情況,也許可以從中找出規(guī)律。

從上面的例子中可以看出:
1)找到被換的數(shù)的位置:從后往前遍歷數(shù)組,找到第一對(duì)num[i] > num[i-1]的數(shù),其中i-1這個(gè)位置的數(shù)是被換的數(shù)。
2)找到替換的數(shù)的位置:這個(gè)位置的數(shù)該填誰(shuí)?從endi,找到第一個(gè)大于num[i-1]的數(shù),與其交換位置即可;因?yàn)閺膃ndi是單調(diào)遞增的,所以第一個(gè)大于num[i-1]的數(shù)是最小的一個(gè);
3)交換位置后,從i~end位置的數(shù),剛好為降序序列;將其改成升序序列即可;
4)如果沒(méi)有找到任何num[i]>num[i-1]的對(duì),那么即為排列的最后一個(gè),此時(shí)我們需要返回排列的第一個(gè),即將整個(gè)降序序列改成升序序列即可。
代碼如下:

public static void nextPermutation(int[] nums) {
        for (int i = nums.length - 1; i > 0; i--) {
            if (nums[i] > nums[i - 1]) {
                // len-1 -> i 找到第一個(gè)大于nums[i-1]的數(shù), 與其交換
                int index = nums.length - 1;
                while (nums[index] <= nums[i - 1]){
                    index--;
                }
                swapRef(nums, i - 1, index);
                // len-1 -> i 倒序變正序
                reverse(nums, i, nums.length - 1);
                return;
            }
        }
        reverse(nums, 0, nums.length - 1);
    }

    public static void swapRef(int[] nums, int ind1, int ind2) {
        int temp = nums[ind1];
        nums[ind1] = nums[ind2];
        nums[ind2] = temp;
    }

    public static void reverse(int[] nums, int start, int end){
        for (int i = start, j = end; i < j; i++, j--) {
            swapRef(nums, i, j);
        }
    }

下一個(gè)更大元素 III


數(shù)學(xué)
找到大于當(dāng)前數(shù)的,并且所有數(shù)字相同的,最小的數(shù);
1)保證所有數(shù)字相同,聯(lián)想到交換操作;
2)大于當(dāng)前數(shù)的最小數(shù),從len-2遍歷到0,對(duì)于數(shù)字nums[i],從nums[i+1]~nums[end],找到大于nums[i]的最小的數(shù),然后交換,完成第一次交換即可。
3)交換之后,這個(gè)數(shù)必然大于之前的數(shù),但是未必是最小的,還需要保證,從i+1到end的數(shù)是從小到大排序的。考慮到交換之前,從i+1到end的數(shù)是降序排列的,交換之后,仍然是降序排列的,所以只需要翻轉(zhuǎn)這部分的數(shù)組即可。

    public int nextGreaterElement(int n) {
        char[] nums = String.valueOf(n).toCharArray();
        for (int i = nums.length - 2; i >= 0; i--) {
            if (nums[i] < nums[i + 1]) {
                int j = nums.length - 1;
                while (nums[j] <= nums[i]) {
                    j--;
                }
                swap(nums, i, j);
                reverse(nums, i + 1, nums.length - 1);
                Long potential = Long.valueOf(new String(nums));
                return potential > Integer.MAX_VALUE ? -1 : Integer.valueOf(new String(nums));
            }
        }
        return -1;
    }

    public void swap(char[] nums, int ind1, int ind2) {
        char temp = nums[ind1];
        nums[ind1] = nums[ind2];
        nums[ind2] = temp;
    }

    public void reverse(char[] nums, int start, int end) {
        int L = start;
        int R = end;
        while (L < R) {
            swap(nums, L, R);
            L++;
            R--;
        }
    }

最佳觀光組合

 public int maxScoreSightseeingPair(int[] A) {
        int maxScore = 0;
        int add = A[0] + 0;
        for (int j = 1; j < A.length; j++) {
            int sub = A[j] - j;
            maxScore = Math.max(maxScore, add + sub);
            add = Math.max(add, A[j] + j); // 因?yàn)楹竺婷總€(gè)sub都是固定的, 所以add只需要選最大的即可
        }
        return maxScore;
    }

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容