剑指offer刷题Day1(C#)

剑指 Offer 09. 用两个栈实现队列

题目描述:

用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 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();
 */

结果如下:

剑指 Offer 30. 包含min函数的栈

题目描述:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 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();
 */

剑指 Offer 24. 反转链表

题目描述:定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

这题,我其实还是不会,但是因为做过好几遍,背出来了。。。。。。

代码如下:
 

/**
 * 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;
        }
    }
}

剑指 Offer 35. 复杂链表的复制

题目描述:

请实现 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;
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值