1. 程式人生 > 其它 >496.下一個更大元素Ⅰ

496.下一個更大元素Ⅰ

目錄

496.下一個更大元素Ⅰ

題目

給你兩個 沒有重複元素 的陣列nums1 和nums2,其中nums1是nums2的子集。

請你找出 nums1中每個元素在nums2中的下一個比其大的值。

nums1中數字x的下一個更大元素是指x在nums2中對應位置的右邊的第一個比x大的元素。如果不存在,對應位置輸出 -1 。

示例 1:

輸入: nums1 = [4,1,2], nums2 = [1,3,4,2].
輸出: [-1,3,-1]
解釋:
    對於 num1 中的數字 4 ,你無法在第二個陣列中找到下一個更大的數字,因此輸出 -1 。
    對於 num1 中的數字 1 ,第二個陣列中數字1右邊的下一個較大數字是 3 。
    對於 num1 中的數字 2 ,第二個陣列中沒有下一個更大的數字,因此輸出 -1 。

示例 2:

輸入: nums1 = [2,4], nums2 = [1,2,3,4].
輸出: [3,-1]
解釋:
   對於 num1 中的數字 2 ,第二個陣列中的下一個較大數字是 3 。
    對於 num1 中的數字 4 ,第二個陣列中沒有下一個更大的數字,因此輸出 -1 。

提示:

1 <= nums1.length <= nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 104
nums1和nums2中所有整數 互不相同
nums1 中的所有整數同樣出現在 nums2 中

來源:力扣(LeetCode)
連結:

https://leetcode-cn.com/problems/next-greater-element-i
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。

題解-暴力解法

根據題目來看,我們需要找到兩個東西
1.nums1[i]在nums裡的位置x
2.x位置後面第一個比nums[i]大的元素

外層迴圈從左到右遍歷nums1,獲取到nums1[i];
內層迴圈從右往左找比nums[i]大的元素,不斷更新元素max,直到找到相等的元素,這樣最後更新的元素就是第一個比它大的值

class Solution {
    public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        int len1 = nums1.length;
        int result[] =new int [len1];
        int max=-1; //初始化為-1,沒找到就是-1
        for(int i=0;i<len1;i++){
            for(int j=nums2.length-1;j>=0;j--){
                if(nums1[i]<nums2[j]){
                    max=nums2[j];
                }
                if(nums1[i]==nums2[j]){ 
                    result[i] = max;
                    max=-1;
                    break;
                }
            }
        }
        return result;
    }
}

題解2-單調棧

單調棧就是棧內得元素保持升序或降序

使用場景
通常是一維陣列,尋找任意一個元素得右邊或者左邊第一個比自己大或者小的元素的位置。時間複雜度為O(n)

本道題就是在nums2中找到第一個比nums1中對應元素大的元素。
那麼本題的result的長度應該和nums1的長度一致,且初始化為-1。

先迴圈nums2,找出每一個元素右邊第一個比他大的元素值,用雜湊表記錄下來(沒有重複元素 的陣列nums1 和nums2)。然後再迴圈nums1從雜湊表中找到結果。
但是nums1是nums2的子陣列,那麼nums2的元素肯定比nums1的多,這樣會浪費很多空間。我們可以先迴圈nums1在hash表中進行記錄,再迴圈nums2,根據nums1的元素尋找第一個比大的值。

入棧的陣列應該是nums2,這一步可以看作是再nums2中找第一個比某元素大的元素,這裡就可以利用昨天題的做法了。

class Solution {
    public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        int len1 = nums1.length;
        int result[] =new int [len1];
        Arrays.fill(result,-1);
Stack<Integer> st = new Stack<>(); //我的棧直接存放的是元素不是下標
HashMap<Integer,Integer> map = new HashMap<>(); 
for(int j=0;j<nums1.length;j++){
    map.put(nums1[j],j); //儲存下標
}
for(int i=0;i<nums2.length;i++){
	 while(!st.empty() && nums2[i]>st.peek()){ //當前元素比棧頂元素大
		 if(map.containsKey(st.peek())){ //如果在nums1中存在
			 result[map.get(st.peek())] = nums2[i]; //需要根據下標設定result
		 }  
		 st.pop();
	 }
	st.push(nums2[i]);
}
        return result;
    }
}