精品推荐:
《征服数据结构》专栏:50多种数据结构彻底征服
《经典图论算法》专栏:50多种经典图论算法全部掌握
一华东师范大学的java开发工程师在美团投简历,直接被拒:不接受本科。美团现在是越来越飘了,本科都不要了。
华东师范大学咋说也是个985,连实习的机会都不给,如果说是能力不行被拒也能理解,可是给出的理由竟然是因为学历是本科。
--------------下面是今天的算法题--------------
来看下今天的算法题,这题是LeetCode的第1019题:链表中的下一个更大节点。
问题描述
来源:LeetCode第1019题
难度:中等
给定一个长度为 n 的链表 head
对于列表中的每个节点,查找下一个更大节点的值。也就是说,对于每个节点,找到它旁边的第一个节点的值,这个节点的值严格大于它的值。
返回一个整数数组 answer ,其中 answer[i] 是第 i 个节点( 从1开始 )的下一个更大的节点的值。如果第 i 个节点没有下一个更大的节点,设置 answer[i] = 0 。
示例1:
输入:head = [2,1,5]
输出:[5,5,0]
示例2:
输入:head = [2,7,4,3,5]
输出:[7,0,5,5,0]
链表中节点数为 n
1 <= n <= 10^4
1 <= Node.val <= 10^9
问题分析
这题让计算每一个节点右边比它大的节点值,我们可以使用单调栈,从栈顶到栈底是单调递增的。
1,如果当前值num比栈顶元素值小,就把当前值num压栈。
2,如果当前值num大于栈顶元素的值,说明栈顶元素遇到了右边比它大的值,栈顶元素出栈,然后num继续和新的栈顶元素比较。
为了方便计算,我们可以先把链表中的节点存储到一个集合中,我们以示例 2 为例画个图看下:
JAVA:
public int[] nextLargerNodes(ListNode head) {
// 先把链表转化为集合list
List<Integer> mList = new ArrayList<>();
while (head != null) {
mList.add(head.val);
head = head.next;
}
int[] ans = new int[mList.size()];
Stack<Integer> stk = new Stack<>();
for (int i = 0; i < ans.length; i++) {
int num = mList.get(i);
while (!stk.isEmpty() && num > mList.get(stk.peek()))
ans[stk.pop()] = num;
stk.push(i);
}
return ans;
}
C++:
public:
vector<int> nextLargerNodes(ListNode *head) {
// 先把链表转化为vector
vector<int> mList;
ListNode *cur = head;
while (cur != nullptr) {
mList.push_back(cur->val);
cur = cur->next;
}
vector<int> ans(mList.size(), 0); // 初始化答案数组为0
stack<int> stk;
for (int i = 0; i < ans.size(); i++) {
int num = mList[i];
while (!stk.empty() && num > mList[stk.top()]) {
ans[stk.top()] = num;
stk.pop();
}
stk.push(i);
}
return ans;
}
Python:
def nextLargerNodes(self, head: Optional[ListNode]) -> List[int]:
# 先把链表转化为集合list
m_list = []
while head is not None:
m_list.append(head.val)
head = head.next
ans = [0] * len(m_list)
stk = []
for i in range(len(ans)):
num = m_list[i]
while stk and num > m_list[stk[-1]]:
ans[stk.pop()] = num
stk.append(i)
return ans
笔者简介
博哥,真名:王一博,毕业十多年,《算法秘籍》作者,专注于数据结构和算法的讲解,在全球30多个算法网站中累计做题2000多道,在公众号中写算法题解800多题,对算法题有自己独特的解题思路和解题技巧,喜欢的可以给个关注,也可以下载我整理的1000多页的PDF算法文档。
数组,稀疏表(Sparse Table),单向链表,双向链表,块状链表,跳表,队列和循环队列,双端队列,单调队列,栈,单调栈,双端栈,散列表,堆,字典树(Trie树),ArrayMap,SparseArray,二叉树,二叉搜索树(BST),笛卡尔树,AVL树,树堆(Treap),FHQ-Treap
……
图的介绍,图的表示方式,邻接矩阵转换,广度优先搜索(BFS),深度优先搜索(DFS),A*搜索算法,迭代深化深度优先搜索(IDDFS),IDA*算法,双向广度优先搜索,迪杰斯特拉算法(Dijkstra),贝尔曼-福特算法(Bellman-Ford),SPFA算法,弗洛伊德算法(Floyd)
……