LeetCode演算法題-Next Greater Element I(Java實現)

weixin_34148456發表於2019-01-29

這是悅樂書的第244次更新,第257篇原創

01 看題和準備

今天介紹的是LeetCode演算法題中Easy級別的第111題(順位題號是496)。你有兩個陣列(沒有重複)nums1和nums2,其中nums1的元素是nums2的子集。在nums2的相應位置找到nums1元素的所有下一個更大的數字。nums1中的數字x的下一個更大數字是nums2中右邊第一個更大的數字。如果它不存在,則輸出該數字的-1。例如:

輸入:nums1 = [4,1,2],nums2 = [1,3,4,2]。

輸出:[-1,3,-1]

說明:對於第一個陣列中的數字4,在第二個陣列中找不到下一個更大的數字,因此輸出-1。對於第一個陣列中的數字1,第二個陣列中的下一個更大數字是3。對於第一個陣列中的數字2,第二個陣列中沒有下一個更大的數字,因此輸出-1。

輸入:nums1 = [2,4],nums2 = [1,2,3,4]。

輸出:[3,-1]

說明:對於第一個陣列中的數字2,第二個陣列中的下一個更大數字是3。對於第一個陣列中的數字4,第二個陣列中沒有下一個更大的數字,因此輸出-1。



注意:

  • nums1和nums2中的所有元素都是唯一的。

  • nums1和nums2的長度不會超過1000。

本次解題使用的開發工具是eclipse,jdk使用的版本是1.8,環境是win7 64位系統,使用Java語言編寫和測試。

02 第一種解法

暴力解法。使用兩層迴圈,先找到nums1的元素在nums2中的對應元素,然後從nums2中找到的元素的下一位往右開始判斷,找到比當前元素大的元素,找得到就將其作為結果陣列的元素新增進去,否則就將-1新增進結果陣列。

public int[] nextGreaterElement(int[] nums1, int[] nums2) {
    int[] result = new int[nums1.length];
    for (int i=0; i<nums1.length; i++) {
        int j = 0, k = 0;
        for (; j<nums2.length; j++) {
            if (nums1[i] == nums2[j]) {
                break;
            }
        }
        for (k = j+1; k<nums2.length; k++) {
            if (nums2[k] > nums2[j]) {
                result[i] = nums2[k];
                break;
            }
        }
        if (k == nums2.length) {
            result[i] = -1;
        }
    }
    return result;
}


03 第二種解法

我們可以將第一種方法進行優化,將nums2中的元素作為key、索引作為value存入HashMap,在原來第一種解法中每次通過迴圈來定位nums2中的索引位置,換成了通過key查詢value的對映,獲取到索引後,從索引後一位開始依次尋找比nums1的當前元素大的數字,找得到就替換已經設值為-1的結果陣列的元素值。

public int[] nextGreaterElement2(int[] nums1, int[] nums2) {
    int[] result = new int[nums1.length];
    Map<Integer, Integer> map = new HashMap<Integer, Integer>();
    for (int i=0; i<nums2.length; i++) {
        map.put(nums2[i], i);
    }
    for (int j=0; j<nums1.length; j++) {
        result[j] = -1;
        int index = map.get(nums1[j]);
        for (int k = index + 1; k<nums2.length; k++) {
            if (nums2[k] > nums1[j]) {
                result[j] = nums2[k];
                break;
            }
        }
    }
    return result;
}


04 第三種解法

使用HashMap和棧。在第二種解法中我們使用HashMap存的是nums2的值、索引,在此解法中,我們使用HashMap存的是,如果nums2的當前元素存在右邊最大數,上一個元素為key,當前元素為value。

在遍歷nums2中的元素時,如果棧不為空,並且當前棧頂的值小於當前元素,即nums2的前一個元素存在右邊最大數,此時,我們需要將棧頂的元素作為key,當前元素作為value,存入HashMap中,同時,要將棧頂的元素移除,此操作是迴圈執行的。最後我們再將nums2的當前元素存入stack中。

接著,我們要開始處理nums1的資料了,遍歷其中的元素,如果能夠在HashMap中找到對應的值,就取其value作為結果陣列的元素值,否則取-1作為預設值。

public int[] nextGreaterElement3(int[] nums1, int[] nums2) {
    int[] result = new int[nums1.length];
    Map<Integer, Integer> map = new HashMap<Integer, Integer>();
    Stack<Integer> stack = new Stack<Integer>();
    for (int num : nums2) {
        while (!stack.isEmpty() && stack.peek() < num) {
            map.put(stack.pop(), num);
        }
        stack.push(num);
    }
    for (int i=0; i<nums1.length; i++) {
        result[i] = map.getOrDefault(nums1[i], -1);
    }
    return result;
}


05 小結

演算法專題目前已日更超過三個月,演算法題文章111+篇,公眾號對話方塊回覆【資料結構與演算法】、【演算法】、【資料結構】中的任一關鍵詞,獲取系列文章合集。

以上就是全部內容,如果大家有什麼好的解法思路、建議或者其他問題,可以下方留言交流,點贊、留言、轉發就是對我最大的回報和支援!

相關文章