【圣诞专场】刷完这套链表套题,面试官考链表的时候我笑出了声(上)

简介: 数据结构与算法的重要性相信大家都已经非常清楚。其中链表更是其中的重中之重,很多兄弟就感觉,诶无非单链表双链表实现增删改查,非常简单。确实,链表虽然简单,但许多兄弟也仅仅是在自己的编译器上完成过链表的这些基础功能。那如何检验自己的链表水平呢?——这里我为大家排好了一套链表专题,题目由简到难,囊括链表所有题型,帮你完美过渡。其中我也附带了自身的详细题解,照着这套题目刷下去,相信大家对于链表的操作更加是得心应手。建议收藏,有空时可根据题目顺序训练。

🍋1.刷题须知与必备能力


       首先这套题目,是建议在大家对链表有一定的了解和掌握的程度上来进行自我检验和训练的。不适合对链表没有了解的小白同学,如果对链表还是小白的同学,建议可以收藏文章日后阅读,同时为大家推荐观看我的链表文章:


       单链表学习——单链表


       双链表学习——双链表


       做链表的题目有条件一定要在草稿纸上演示流程,不要凭空想象,这是大忌!!!


🍇2.有序刷题,循序渐进


🌿1.移除链表元素(简单)


       给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。


       题目链接:移除链表元素


       这道题比较基础,为了帮助大家入门,所以讲的比较细致。三种方法都希望大家自己手写一下并且理解掌握。      


方法1:链表的定义本身带有递归性质,可以通过递归的方法求解。


class Solution {
    public ListNode removeElements(ListNode head, int val) {
        //递归出口
        if (head == null) {
            return head;
        }
        //递归调用
        head.next = removeElements(head.next, val);
        return head.val == val ? head.next : head;
    }
}

        方法2,3: 删除的时候,我们需要考虑一种情况,就是头结点是否是我们需要删除的节点,因为删除头结点的步骤和后面的节点会有所不同。这时我们可以设置一个虚拟的头结点放在真正的头结点前,这样就可以统一完成所有节点的删除步骤,当然也可以在将头结点单独来处理删除 ,这里我将两种代码都写出来了,供大家参考。      


//有虚拟头结点的方法
class Solution {
    public ListNode removeElements(ListNode head, int val) {
        if(head==null) return head;
        //设置虚拟头结点a,next接上真正的头结点
        ListNode a=new ListNode(-1,head);
        //b节点用来遍历链表
        ListNode b=a;
        while(b.next!=null){
            if(b.next.val==val){
                b.next=b.next.next;
            }else{
                b=b.next;
            }
        }
        //注意这里得写a.next不能写head
        return a.next;
    }
}
//不设虚拟头结点
class Solution {
    public ListNode removeElements(ListNode head, int val) {
        //删除值相同的头结点后,可能新的头结点也值相等,用循环解决
        while(head!=null&&head.val==val){
            head=head.next;
        }
        if(head==null)
            return head;
        ListNode prev=head;
        //确保当前结点后还有结点
        while(prev.next!=null){
            if(prev.next.val==val){
                prev.next=prev.next.next;
            }else{
                prev=prev.next;
            }
        }
        return head;
    }
}


🌿2.设计链表(中等)


       设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性:val 和 next。val 是当前节点的值,next 是指向下一个节点的指针/引用。如果要使用双向链表,则还需要一个属性 prev 以指示链表中的上一个节点。假设链表中的所有节点都是 0-index 的。


       题目链接:设计链表


       这道题能很好检验我们对链表的掌握能力,它需要我们实现指定的功能,大家一定要完成它。        


class MyLinkedList {
    //虚拟头结点
    Node head;
    //用来记录元素个数
    int N;
    class Node{
        int val;
        Node next;
        public Node(){}
        public Node(int val){
            this.val=val;
        }
    }
    //构造方法
    public MyLinkedList() {
        this.head=new Node(0);
        this.N=0;
    }
    //获取第index个节点的数值
    public int get(int index) {
        //如果index非法,返回-1
        if (index < 0 || index >= N) {
            return -1;
        }
        Node currentNode = head;
        //包含一个虚拟头节点,所以查找第 index+1 个节点
        for (int i = 0; i <= index; i++) {
            currentNode = currentNode.next;
        }
        return currentNode.val;
    }
    //在链表最前面插入一个节点
    public void addAtHead(int val) {
        addAtIndex(0, val);
    }
     //在链表的最后插入一个节点
    public void addAtTail(int val) {
        addAtIndex(N, val);
    }
    //完成制定插入
    public void addAtIndex(int index, int val) {
        //非法直接返回
        if(index>N){
            return;
        }
        //index<0的情况和等于0是一样的
        if(index<0){
            index=0;
        }
        Node curr=head;
        //找到待插入位置的前一个节点
        for(int i=0;i<index;i++){
            curr=curr.next;
        }
        //完成插入操作
        Node newNode=new Node(val);
        newNode.next=curr.next;
        curr.next=newNode;
        N++;
    }
    public void deleteAtIndex(int index) {
        //索引非法直接return
        if(index<0||index>=N) return;
        Node pre=head;
        //找到待插入的前一个节点
        for(int i=0;i<index;i++){
            pre=pre.next;
        }
        pre.next=pre.next.next;
        N--;
    } 
}


相关文章
|
6月前
【面试必刷TOP101】删除链表的倒数第n个节点 & 两个链表的第一个公共结点
【面试必刷TOP101】删除链表的倒数第n个节点 & 两个链表的第一个公共结点
23 0
|
6月前
|
测试技术
【面试必刷TOP101】合并k个已排序的链表 & 判断链表中是否有环
【面试必刷TOP101】合并k个已排序的链表 & 判断链表中是否有环
35 0
|
6月前
【面试必刷TOP101】反转链表 & 链表内指定区间反转
【面试必刷TOP101】反转链表 & 链表内指定区间反转
35 0
|
6月前
【数据结构】链表面试题
【数据结构】链表面试题
24 0
|
6月前
【LeetCode】1171. 从链表中删去总和值为零的连续节点、面试题 02.05. 链表求和
目录 1171. 从链表中删去总和值为零的连续节点 面试题 02.05. 链表求和
33 0
|
1月前
|
存储 算法
【数据结构与算法】【腾讯阿里链表面试题】算法题--链表易懂版讲解
【数据结构与算法】【腾讯阿里链表面试题】算法题--链表易懂版讲解
|
1月前
|
存储 算法 Java
【数据结构与算法】2、链表(简单模拟 Java 中的 LinkedList 集合,反转链表面试题)
【数据结构与算法】2、链表(简单模拟 Java 中的 LinkedList 集合,反转链表面试题)
43 0
|
4月前
|
算法 Java 程序员
【Java程序员面试专栏 数据结构篇】二 高频面试算法题:链表
【Java程序员面试专栏 数据结构篇】二 高频面试算法题:链表
135 0
|
5月前
|
算法
代码随想录算法训练营第四天 | LeetCode 24. 两两交换链表中的节点、19.删除链表的倒数第N个节点、面试题 02.07. 链表相交、142.环形链表II
代码随想录算法训练营第四天 | LeetCode 24. 两两交换链表中的节点、19.删除链表的倒数第N个节点、面试题 02.07. 链表相交、142.环形链表II
141 0
|
5月前
|
存储 算法
代码随想录算法训练营第四天 | 24. 两两交换链表中的节点 ,19.删除链表的倒数第N个节点 ,面试题 02.07. 链表相交 ,142.环形链表II
代码随想录算法训练营第四天 | 24. 两两交换链表中的节点 ,19.删除链表的倒数第N个节点 ,面试题 02.07. 链表相交 ,142.环形链表II