剑指offer刷题笔记

删除链表中重复的结点:较难

在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。

例如,链表1->2->3->3->4->4->5 处理后为 1->2->5

public class Solution {
    public ListNode deleteDuplication(ListNode pHead)
    {
        if(pHead==null||pHead.next==null)return pHead;
        ListNode p0=new ListNode(-2147483648);//构造前站节点来防止第一个节点被删除的惨剧
        ListNode p1=p0;
        ListNode p2=pHead;
        int temp=pHead.val;
        int dup=0;//dup==1表示有重复
        while (p2.next!=null){//循环外还有处理?
            if(p2.next.val==temp){
                dup=1;
                p2=p2.next;//
            }
            else{
                if (dup==0){
                    p1.next=p2;
                    p1=p1.next;
                }
                dup=0;
                temp=p2.next.val;
                p2=p2.next;
            }
        }
        if (dup==0)p1.next=p2;
        if (dup==1)p1.next=null;//p1每次接收都是后面一串
        
        p0=p0.next;//过河拆桥,去掉头部哨兵
        return p0;
    }
}

 

 

包含min函数的栈:中等

定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。

import java.util.Stack;
public class Solution {
    //成员变量:
    private static Stack stack1=new Stack();//stack1这个是基础栈,用于栈的基础功能
    private static Stack stack2=new Stack();//这个是保存stack1对应位置的最小值的栈,和stack1的大小始终保持一致
    //例子:stack1:342053
    //例子:stack2:332000
    private Integer min=new Integer(Integer.MAX_VALUE);//这里使用Integer.MAX_VALUE来初始化,其实使用任意值都可以,但是有括号的话里面不能为空
//也可以用:private Integer min=Integer.MAX_VALUE
//也可以用:private Inreger min=0;
//4个方法:
    public void push(int node) {
        if(stack1.empty()){
            min=node;
            stack1.push(node);
            stack2.push(min);
        }
        else{
            if (node<min){
                min=node;
            }
            stack1.push(node);
            stack2.push(min);
        }
    }
    
    public void pop() {   //pop()不用返回值
        if (stack1.empty()){
            return ;
        }
        stack1.pop();
        stack2.pop();//pop()的意思是:将栈顶的值除掉。这题里面不返回值(void类型)
    }
    
    public int top() {
        return stack1.peek();//peek()的意思是:不改变栈,观察栈顶的值
    }
    
    public int min() {
        return stack2.peek();
    }
}

 

孩子们的游戏(圆圈中最后剩下的数):中等

每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0...m-1报数....这样下去....直到剩下最后一个小朋友,可以不用表演,并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!^_^)。请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1)

public class Solution {
    public int LastRemaining_Solution(int n, int m) {
        if (n<1||m<1)return -1;//??
        ListNode head=new ListNode(0);
        ListNode p=head;
        for (int i=1;i){
            ListNode kids=new ListNode(i);
            p.next=kids;
            p=p.next;
        }
        p.next=head;//p回到开头位置的前一个,做准备
        while(p.next!=p){//注意这里的条件是:环形链中p不指向自身
            for (int i=0;i){
                p=p.next;
            }
            p.next=p.next.next;//java会自动回收,所以不管那个被删除的节点
        }
        return p.val;
    }
}

 

复杂链表的复制:较难

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)

ps:原链表保持不变(改动后要还原)

 

/*
public class RandomListNode {
    int label;
    RandomListNode next = null;
    RandomListNode random = null;

    RandomListNode(int label) {
        this.label = label;
    }
}
*/
public class Solution {
    public RandomListNode Clone(RandomListNode pHead)
    {
        if (pHead==null)return null;
        RandomListNode p1=pHead;//沿着主链
        RandomListNode p2=pHead.next;//在前
        while(p1!=null){
            RandomListNode node=new RandomListNode(p1.label);
            p1.next=node;
            p1.next.next=p2;
            p1=p2;
            if (p2!=null)p2=p2.next;//用末尾来验证,几乎每个while循环的末尾都要画图验证!!!
        }
        p1=pHead;
        while (p1!=null){
            if (p1.random==null)p1.next.random=null;//要判断下,防止为空
            else{
                p1.next.random=p1.random.next;//太强了
            }
            p1=p1.next.next;//可以√
        }

        RandomListNode head=pHead.next;
        p2=pHead.next;
        p1=pHead;//需要保持原有的链表为初始状态(还原)
        while (p2.next!=null){
            p1.next=p1.next.next;//
            p1=p1.next;//
            p2.next=p2.next.next;
            p2=p2.next;
        }
        p1.next=null;////(终止的时候要画图来试一下)


/*
        p2=pHead.next;
        p1=pHead;
        while(p1!=null){
            p1.next=p2.next;
            p1=p1.next;
            if (p2.next!=null)p2.next=p2.next.next;
            p2=p2.next;
        }
*/

        return head;
        
    }
}

 

链表中环的入口结点:

给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
ps:题目很坑,不给修改val的值。
import java.util.ArrayList;//
public class Solution {
    public ListNode EntryNodeOfLoop(ListNode pHead)
    {
        ArrayList list=new ArrayList<>();//注意初始化的模式,链表节点可以在<>中,类比int
        if(pHead==null)return null;
        ListNode p=pHead;
        while(p!=null){
            if (list.contains(p))return p;//list.contains()和list.add()的运用
            list.add(p);
            p=p.next;
        }
        return null;
    }
}

/*
public class Solution {  //如果可以修改val的值,那么就很简单了,如下:
    public ListNode EntryNodeOfLoop(ListNode pHead)
    {
        if(pHead==null)return null;
        ListNode p=pHead;
        while(p!=null){
            if (p.val==2199)return p;
            p.val=2199;
            p=p.next;
        }
        return null;
    }
}
*/

 

你可能感兴趣的:(剑指offer刷题笔记)