leetcode_1019:链表中的下一个更大节点

这个题目我第一次看到太简单了吧,暴力就完事了,果不其然,时间复杂度很高,当然结果也是过了,没什么难度:

    public int[] nextLargerNodes(ListNode head) {
        List<Integer> result = new LinkedList<>();
        while (head != null) {
            ListNode p = head.next;
            while (p != null) {
                if (p.val > head.val) {
                    result.add(p.val);
                    break;
                }
                p = p.next;
            }
            if (p == null)
                result.add(0);
            head = head.next;
        }
        int[] finalResult = new int[result.size()];
        for (int i = 0; i < finalResult.length; ++i) {
            finalResult[i] = result.get(i);
        }
        return finalResult;
    }

但是能看到这个题目是一个中等难度的题目,所以肯定不是这么简单的。而且在做的过程中我看到了结果中有很多重复的元素,所以真相只有一个:我不会!!!

其实我是思考了的,当然就是简单的思考,反正也是错了就不说了,直接看的答案。然后第一眼看上去有单调栈动态规划,听于是还没看下面我就想先自己尝试重新写一次。当然动态规划我前一段刚学过并做了借个题目,于是先写动态规划。


动态规划

dp的递推公式为:

  1. if nums[i + 1] > nums[i] then dp[i] = nums[i + 1]
  2. if nums[i + 1] == nums[i] then dp[i] = dp[i + 1]
  3. else dp[i] = { 遍历 dp[i + 1] … dp[n],寻找最近大于 nums[i] 的值,遇到 0 停止遍历,遇到 0 表示后面没有更大的值了 }
    public static int[] nextLargerNodes1(ListNode head) {
        List<Integer> temp = new LinkedList<>();
        ListNode p = head;
        while (p != null) {
            temp.add(p.val);
            p = p.next;
        }
        int numLength = temp.size();
        int[] nums = new int[numLength];	//存放所有数据的数组
        nums[numLength-1] = temp.get(numLength-1);
        int[] dp = new int[numLength];		//动态规划数组
        dp[numLength-1] = 0;
        int[] result = new int[numLength];	//存放最终结果的数组
        for (int i = nums.length-2; i >= 0; --i) {
            nums[i] = temp.get(i);
            if(nums[i] < nums[i+1]) {
                dp[i] = nums[i+1];
                result[i] = nums[i+1];
            } else if (nums[i] == nums[i+1]) {
                dp[i] = dp[i+1];
                result[i] = dp[i+1];
            } else {
                int j = i;
                for (; j < numLength; ++j) {
                    if (nums[j] > nums[i]) {
                        dp[i] = nums[j];
                        result[i] = nums[j];
                        break;
                    }
                }
                if (j == numLength) {
                    dp[i] = 0;
                    result[i] = 0;
                }
            }
        }
        return result;
    }

单调栈

单调栈的思路就是从前往后遍历,让栈内元素始终是递减的,如果遇到一个元素比栈顶大,说明不能满足递减,则把栈内所有比当前元素小的都出栈,且对应的result值就是当前元素。直到遇到一个比当前元素大的栈顶停止,并将当前元素入栈。
最后将所有栈内元素出栈,且对应的值全部设置为0。这里我们在栈内保存的有两个元素,一个是链表的值,一个是值所在的位置。

    public int[] nextLargerNodes(ListNode head) {
    	//先统计一下有多少个元素
        int numLenght = 0;
        ListNode p = head;
        while (p != null) {
            numLenght++;
            p = p.next;
        }
        int[] result = new int[numLenght];
		//栈应该存放两个值,一个是节点值,一个是节点所处位置(下标,方便在result中设置值)
        Stack<Pair<Integer, Integer>> stack = new Stack<>();
        stack.push(new Pair<>(head.val, 0));    //放第一个元素的值,及对应的下标0
        p = head.next;
        int index = 1;	//记录每个节点的位置
        while (p != null) {
        	//如果大于栈顶,则把所有小于当前p的值出栈,并设置为p.val
            while (!stack.isEmpty() && p.val > stack.peek().getKey()) {        
                Pair<Integer, Integer> curPair = stack.pop();
                result[curPair.getValue()] = p.val;		//result中对应下标设置为当前值
            }
            stack.push(new Pair<>(p.val, index));
            p = p.next;
            index++;
        }
        //将栈内剩余的元素出栈,并设置对应位置的值为0
        while (!stack.isEmpty()) {
            Pair<Integer, Integer> curPair = stack.pop();
            result[curPair.getValue()] = 0;
        }
        return result;
    }

好了,又get到了一些技能…

发布了96 篇原创文章 · 获赞 2 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/reachwang/article/details/103330323
今日推荐