题目描述:
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
纵观这道题可以发现一个坑,栈原本是“后进先出”的,但这道题要求“先进先出,后进后出”,那就只能在压进一个栈以后,再压进另外一个栈里,再pop(),代码如下:
public class CQueue
{
private Stack<int> stack1;
private Stack<int> stack2;
public CQueue()
{
stack1 = new Stack<int>();
stack2 = new Stack<int>();
}
public void AppendTail(int value)
{
stack1.Push(value);
}
public int DeleteHead()
{
if (stack2.Count == 0)
{
while (stack1.Count != 0)
{
stack2.Push(stack1.Pop());
}
}
if (stack2.Count == 0)
{
return -1;
}
else
{
int deleteItem = stack2.Pop();
return deleteItem;
}
}
}
/**
* Your CQueue object will be instantiated and called as such:
* CQueue obj = new CQueue();
* obj.AppendTail(value);
* int param_2 = obj.DeleteHead();
*/
结果如下:
题目描述:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。
难得今天人品好,一遍过,但是结果却不太好,代码和结果如下:
public class MinStack {
Stack<int> Stack1 = new Stack<int>();
/** initialize your data structure here. */
public MinStack() {
}
public void Push(int x) {
Stack1.Push(x);
}
public void Pop() {
Stack1.Pop();
}
public int Top() {
int x = Stack1.Peek();
return x;
}
public int Min() {
int[] StackArray = Stack1.ToArray();
int min = StackArray[0];
for (int i=0;i<StackArray.Length;i++){
if(StackArray[i]<min){
min = StackArray[i];
}
}
return min;
}
}
/**
* 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.Min();
*/
看了解析以后,发现可以用两个Stack来整,一个栈正常存储,一个栈从大到小存储,原理如下:
简单来说就是, B栈存储的时候必须是非增的,为什么说是非增的呢,举个特例就行:
代码如下:
public class MinStack {
Stack<int> Stack1 = new Stack<int>();
Stack<int> Stack2 = new Stack<int>();
/** initialize your data structure here. */
public MinStack() {
}
public void Push(int x) {
Stack1.Push(x);
if (Stack2.Count()==0||x <= Stack2.Peek()){
Stack2.Push(x);
}
}
public void Pop() {
if(Stack1.Peek()==Stack2.Peek()){
Stack2.Pop();
}
Stack1.Pop();
}
public int Top() {
return Stack1.Peek();
}
public int Min() {
return Stack2.Peek();
}
}
/**
* 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.Min();
*/
题目描述:定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
这题,我其实还是不会,但是因为做过好几遍,背出来了。。。。。。
代码如下:
/**
* Definition for singly-linked list.
* public class ListNode {
* public int val;
* public ListNode next;
* public ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode ReverseList(ListNode head) {
if(head==null||head.next==null){
return head;
}
else{
ListNode Newhead = ReverseList(head.next);
head.next.next = head;
head.next = null;
return Newhead;
}
}
}
题目描述:
请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/fu-za-lian-biao-de-fu-zhi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
按照国际惯例,迭代永远比递归要好理解🤔 所以先来看迭代的做法
原理如下:
1)先新开出新链表的内存,开的方式比较特别:为了便于确定位置,复制结点就在其复制的那个结点的后面。即将原本的A→B→C,变成A→A'→B→B'→C→C'。
2)在A→A'→B→B'→C→C'中赋值random正确指向的结点
3)然后从A→A'→B→B'→C→C'中,将A'→B'→C' 独立出来输出
代码如下:
/*
// Definition for a Node.
public class Node {
public int val;
public Node next;
public Node random;
public Node(int _val) {
val = _val;
next = null;
random = null;
}
}
*/
public class Solution {
public Node CopyRandomList(Node head) {
if (head == null) {
return null;
}
for (Node node = head; node != null; node = node.next.next) {
Node nodeNew = new Node(node.val);
nodeNew.next = node.next;
node.next = nodeNew;
}
for (Node node = head; node != null; node = node.next.next) {
Node nodeNew = node.next;
nodeNew.random = (node.random != null) ? node.random.next : null;
}
Node headNew = head.next;
for (Node node = head; node != null; node = node.next) {
Node nodeNew = node.next;
node.next = node.next.next;
nodeNew.next = (nodeNew.next != null) ? nodeNew.next.next : null;
}
return headNew;
}
}