面试经典150题(55-58)

leetcode 150道题 计划花两个月时候刷完,今天(第二十四天)完成了4道(55-58)150:

55.(19. 删除链表的倒数第 N 个结点)题目描述:

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

第一版(我记得这个有个快慢指针,但是就是不知道咋做,第一版还是求出长度后找出要删除的去删除。)

class Solution {
    
    
    public ListNode removeNthFromEnd(ListNode head, int n) {
    
    
        ListNode temp=head;
        int len=0;
        // 求出长度
        while(temp!=null){
    
    
            len++;
            temp=temp.next;
        }
        // 删除 倒数 第 n 个
        len=len-n;
        ListNode dumpHead=new ListNode(0);
        dumpHead.next=head;
        temp=dumpHead;
        while(temp!=null){
    
    
            if(len==0&&temp.next!=null){
    
    
               ListNode remove=temp.next;
               temp.next=remove.next;
               break;
            }
            len--;
            temp=temp.next;
        }
        return dumpHead.next;
    }
}

第二版(快慢指针,给快指针先走 n次 题目里的倒数的 n次,当快指针到最后一个时候,慢指针刚好就是要删除的前一个指针了)

class Solution {
    
    
    public ListNode removeNthFromEnd(ListNode head, int n) {
    
    
        ListNode dumpHead=new ListNode(0);
        dumpHead.next=head;

        ListNode low=dumpHead;
        ListNode fast=dumpHead;
        while(fast!=null&&n>0){
    
    
            n--;
            fast=fast.next;
        }
        while(fast!=null&&fast.next!=null){
    
    
            fast=fast.next;
            low=low.next;
        }
        if(low.next!=null){
    
    
            low.next=low.next.next;
        }
        return dumpHead.next;
    }
}

56.(82. 删除排序链表中的重复元素 II)题目描述:

给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。
输入:head = [1,2,3,3,4,4,5]
输出:[1,2,5]

第一版(算是模拟出来的。。)

class Solution {
    
    
    public ListNode deleteDuplicates(ListNode head) {
    
    
        // 只要是 head 第一个节点可能会被删除,就可以选择新增一个辅助节点避免
        ListNode dumpHead=new ListNode(2000);
        dumpHead.next=head;
        ListNode res=dumpHead;
        ListNode preNode=dumpHead;
        while(res!=null){
    
    
            if(res.next==null)
                break;
            ListNode temp=res.next;
            while(temp!=null&&temp.val==res.val){
    
    
                temp=temp.next;
            }
            // 不相等说明当前res节点到temp之前的都要删除的
            if(res.next!=temp){
    
    
                res.next=temp;
                preNode.next=temp;
            }
            else{
    
    
                // 记录上一个节点
                preNode=res;
            }
            res=res.next;
            
        }
        return dumpHead.next;
    }
}

57.(61. 旋转链表)题目描述:

给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置

第一版(这个其实和第一个差不多,相当于找出来倒数第几个节点,然后截断作为头,连接上原来链表的头)

class Solution {
    
    
    public ListNode rotateRight(ListNode head, int k) {
    
    
        ListNode temp=head;
        int len=0;
        ListNode lastNode=head;
        while(temp!=null){
    
    
            len++;
            lastNode=temp;
            temp=temp.next;
        }
        if(len<=1||k%len==0){
    
    
            return head;
        }
        k%=len;
        len-=k;
        temp=head;
        for(int i=0;i<len-1;i++){
    
    
            temp=temp.next;
        }
        ListNode res= temp.next;
        temp.next=null;
        lastNode.next=head;
        return res;
    }
}

58.(86. 分隔链表)题目描述:

给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。
你应当 保留 两个分区中每个节点的初始相对位置。

第一版(这个我真的想了很久。。虽然写出来了,但是还是一坨,只要你舍得用变量,链表的都还可以)

class Solution {
    
    
    public ListNode partition(ListNode head, int x) {
    
    
        ListNode dumpHead=new ListNode(-2000,head);
        ListNode temp=dumpHead;
        ListNode preNode=dumpHead;
        while(temp!=null){
    
    
            if(temp.val>=x){
    
    
                break;
            }
            // 这个是记录后面的数据小于x的要插入的头节点
            preNode=temp;
            temp=temp.next;
        }
        // 这个 lastPreNode 是记录下半段的,后面把小于 x 的 节点要放到 
        //第一个PreNode 的前面,导致 链表断开了,所以记录一下再连接起来
        ListNode lastPreNode=preNode;
        while(temp!=null){
    
    
            ListNode tempNext=temp.next;
            if(temp.val<x){
    
    
                ListNode next=preNode.next;
                temp.next=next;
                preNode.next=temp;
                preNode=preNode.next;
                lastPreNode.next=tempNext;
            }
            else{
    
    
                lastPreNode=temp;
            }
            temp=tempNext;
        }
        return dumpHead.next;

    }
}

第二版(看了解题,我感觉我真的是傻逼。。)

class Solution {
    
    
    public ListNode partition(ListNode head, int x) {
    
    
        ListNode smallHead=new ListNode(0);
        ListNode smallTemp=smallHead;
        ListNode largeHead=new ListNode(0);
        ListNode largeTemp=largeHead;
        while(head!=null){
    
    
            if(head.val<x){
    
    
                smallTemp.next=head;
                smallTemp=smallTemp.next;
            }else{
    
    
                largeTemp.next=head;
                largeTemp=largeTemp.next;
            }
            head=head.next;
        }
        smallTemp.next=largeHead.next;
        largeTemp.next=null;
        return smallHead.next;
    }
}

链表真的不是我说有点难的。。如果不会了可以多搞几个变量可能会稍微清晰一点。

第二十四天啦!!!为跳好槽而 leetcode !!!

猜你喜欢

转载自blog.csdn.net/weixin_44061648/article/details/135280650