155. Min Stack
Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.
- push(x) – Push element x onto stack.
- pop() – Removes the element on top of the stack.
- top() – Get the top element.
- getMin() – Retrieve the minimum element in the stack.
Example:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> Returns -3.
minStack.pop();
minStack.top(); --> Returns 0.
minStack.getMin(); --> Returns -2.
Solution in C++:
关键点:
- 最小值的获取为常量级操作得用空间换取时间
思路:
- 开始准备用一个min变量来存储最小值,但是发现这种方法在弹出最小值后无法动态获取当前的最小值,所以转换为用一个min数组去存当前状态的栈的最小值。
- 看了一些讨论,我这里用vector的方式去实现栈的方式有点偷懒,看到别人有用链表的形式实现。
方法一 :vector
class MinStack {
// attribute
vector<int> stack;
vector<int> min;
public:
/** initialize your data structure here. */
MinStack() {
min.push_back(INT_MAX);
}
void push(int x) {
stack.push_back(x);
if (x < min.back())
min.push_back(x);
else
min.push_back(min.back());
}
void pop() {
stack.pop_back();
min.pop_back();
}
int top() {
return stack.back();
}
int getMin() {
return min.back();
}
};
/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(x);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.getMin();
*/
方法二:linked list
MinStack *head;
MinStack *next;
int min;
int val;
/** initialize your data structure here. */
public:
MinStack() {
head = nullptr;
next = nullptr;
}
void push(int x) {
if(head==nullptr){
head = new MinStack();
head->min=x;
head->val=x;
}
else{
MinStack *newHead = new MinStack();
newHead->val=x;
newHead->min = (int)fmin(head->min,x);
newHead->next = head;
head = newHead;
}
}
void pop() {
head = head->next;
}
int top() {
return head->val;
}
int getMin() {
return head->min;
}
160. Intersection of Two Linked Lists
Write a program to find the node at which the intersection of two singly linked lists begins.
For example, the following two linked lists:
A: a1 → a2
↘
c1 → c2 → c3
↗
B: b1 → b2 → b3
begin to intersect at node c1.
Notes:
- If the two linked lists have no intersection at all, return null.
- The linked lists must retain their original structure after the function returns.
- You may assume there are no cycles anywhere in the entire linked structure.
- Your code should preferably run in O(n) time and use only O(1) memory.
Credits:
Special thanks to @stellari for adding this problem and creating all test cases.
Solution in C++:
关键点:
- 转换成环思路
思路:
- 开始只有暴力的思路,固定一个链表然后在另一个链表中找是否存在相同的,找到即为第一个交点。思索好久只能再想到昨天的hash没有其他办法了。
- 然后看完解析之后,发现还有跟昨天判断是否为环的方法类似的,就是逻辑上将两个链表链接在一起,如果遍历两遍两个链表一定会相遇,此时为第一个交点,为空即没有交点。
方法一 暴力
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *ptrA = headA;
ListNode *ptrB = headB;
for (;ptrA; ptrA = ptrA->next)
{
ListNode *tmp = headB;
for(;tmp; tmp = tmp->next)
{
if(ptrA->val == tmp->val)
if(ptrA == tmp)
return tmp;
}
}
return nullptr;
}
};
方法二 逻辑环
- 弱鸡版
// 判断是否有交集
ListNode *ptrA = headA;
ListNode *ptrB = headB;
ListNode *lastA = nullptr;
ListNode *lastB = nullptr;
while(ptrA){
if(ptrA->next == nullptr){
lastA = ptrA;
break;
}
ptrA = ptrA->next;
}
while(ptrB){
if(ptrB->next == nullptr){
lastB = ptrB;
break;
}
ptrB = ptrB->next;
}
if(lastA == nullptr || lastB == nullptr || lastA != lastB)
{
return nullptr;
}
ptrA = headA;
ptrB = headB;
while(true){
if (ptrA == ptrB)
{
return ptrA;
}
if(ptrA->next == nullptr)
ptrA = headB;
else
ptrA = ptrA->next;
if(ptrB->next == nullptr)
ptrB = headA;
else
ptrB = ptrB->next;
}
- 大神版
ListNode *cur1 = headA, *cur2 = headB;
while(cur1 != cur2){
cur1 = cur1?cur1->next:headB;
cur2 = cur2?cur2->next:headA;
}
return cur1;
小结
今天主要掌握了栈的实现、空间换时间的思路、判断两个链表的相交问题以及如何获取第一个相交点。同时也对昨天在判断环中的方法又应用了一遍,加深了印象。还get了一个报错信息原因。
知识点
-
member access within null pointer of type ‘struct ListNode’
这个问题主要是由于测试系统不知道当前的结点与结点的下一个结点是否为NULL,而自己有没有声明,所以系统不确定,于是就报错。这也说明了链表中的结点使用的时候比其他数据结构要严格一些,一定要时刻保证使用的结点不为NULL,为NULL要做出相应处理。 -
栈的实现
-
链表相交问题