单链表OJ面试题(重点)

本文主要涵盖了常见的链表操作面试题,包括删除指定值节点、反转链表、寻找中间节点、查找倒数第k个节点、合并有序链表、按值分割链表、删除重复节点、判断回文结构、寻找链表交点、检测环形链表及找出环的起点等。这些题目旨在考察对链表数据结构的理解和操作能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

OJ面试题

1. 删除一个链表所有值为key的节点


    public void removeAllKey(int key) {
         Node pre = this.head;
         Node cur =this.head.next;
         while (cur!=null){
             if (cur.data == key){
                 pre.next = cur.next;
                 cur = cur.next;
                 size--;
             }else {
                 pre = cur;
                 cur = cur.next;
             }

         }
         if(this.head.data==key){
             head = head.next;
         }
    }

2. 反转一个单链表

    public Node reverseList(){
       Node reverseHead = null; //反转后新的头节点
        Node cur = this.head;  //cur代表当前需要反转的节点
        Node prev = null;   //cur的前驱信息
        while (cur!= null){
            Node curNext = cur.next;
           if(curNext == null){
               reverseHead = cur;
           }
            cur.next = prev;
            prev = cur;
            cur = curNext;
        }
        return reverseHead;
    }

3. 找到单链表的中间节点

    public Node middleNode(){
        Node cur = this.head;
        int len = getLength()/2;
        for(int i = 0;i<len;i++){
            cur = cur.next;
        }
        return cur;
    }

4. 找到单链表的倒数第k个节点


    public Node findKthToTail(int k){
       if(this.head==null || k<=0 ){
           return null;
       }
        Node fast = this.head;
        Node slow = this.head;

        for(int i = 0;i<k-1;i++){
            if(fast.next!=null){
                fast = fast.next;
            }else{
                System.out.println("没有这个节点");
                return null;
            }
        }
        while (fast.next!=null){
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }

5. 合并两个有序链表

public Node mergeTwoLists(Node headA,Node headB){
        
     Node newHead = new Node(-1);//虚拟节点
     Node tmpHead = newHead;
        //谁小串谁
        while (headA!=null && headB!=null){
            if(headA.getData()>=headB.getData()){
                tmpHead.next = headB;
                tmpHead = tmpHead.next;
                headB = headB.next;
            }else {
                tmpHead.next = headA;
                tmpHead = tmpHead.next;
                headA = headA.next;
            }
        }
        if(headA!=null){
            tmpHead.next = headA;
        }
        if(headB!=null){
            tmpHead.next = headB;
        }
        return newHead.next;
    }

6. 给定x为基准将链表分割成两部分,所有小于x的节点排在大于等于x的节点之前


    public Node partition(int x){
        Node beforeStart = null;
        Node beforeEnd = null;
        Node lastStart = null;
        Node lastEnd = null;
        Node cur = this.head;
        while (cur!=null){
            Node curNext = cur.next;
            cur.next = null;
            if(cur.data < x){   //前半部分
                if(beforeStart==null){  //放第一个节点
                    beforeStart = cur;
                    beforeEnd = beforeStart;
                } else {
                    beforeEnd.next = cur;
                    beforeEnd = cur;
                }
            }else {  //后半部分
                if(lastStart ==null){  //放第一个节点
                    lastStart = cur;
                    lastEnd = cur;
                } else {
                    lastEnd.next = cur;
                    lastEnd = lastEnd.next;
                }
            }
            cur = curNext;
        }
        if(beforeStart == null){  //如果没有比x小的
            return lastStart;
        }
        beforeEnd.next = lastStart;  // 拼接单链表

        return beforeStart;
    }

7. 删除有序链表中重复节点,不保留重复节点,返回头指针

    public Node delectDuplication(){
        Node node = new Node(-1);
        Node cur = this.head;
        Node tmpHead = node;  //虚拟节点
        while (cur!=null){
            if(cur.next!=null && cur.data == cur.next.data){
                while (cur.next!=null && cur.data == cur.next.data){
                    cur = cur.next;
                }
                cur = cur.next;
                tmpHead.next = cur;
            } else {
                //确定不为重复节点
                tmpHead.next = cur;
                tmpHead = cur;
                cur = cur.next;
            }
        }
        return node.next;

    }

8 . 链表的回文结构

    public boolean chkPalindrme(){
        Node fast = this.head;
        Node slow = this.head;
        while (fast!=null && fast.next!=null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        //slow指向中间节点
        Node p = slow.next;
        Node pNext = p.next;
        while (p!=null){  //链表后半部分逆置
            p.next = slow;
            slow = p;
            p = p.next;
            if(p!=null){
                pNext = p.next;
            }
        }
        //后半部分已经逆置
        while (this.head != slow){
            if(this.head.data!=slow.data){
                return false;
            }
            if(this.head.next==slow){ //偶数个
                return true;
            }
            head = head.next;
            slow = slow.next;
        }
        return true;
    }

9. 输入两个链表,找到相交节点

    public  Node getIntersectionNode( Node headA, Node headB){
        Node pL = headA;
       Node pS = headB;
        int lenA = 0;
        while (pL!=null){
            lenA++;
            pL = pL.getNext();
        }
        int lenB = 0;
        while (pS!=null){
            lenB++;
            pS = pS.getNext();
        }
        pL = headA;  //起初假设A链表长
        pS = headB;
        int len = lenA-lenB;
        if(len<0){
           pL = headB;  //B单链表是长的
           pS = headA;
           len = lenB-lenA;
        }
        //最长的单链表是PL,并且差值是一个正数
        for(int i = 0;i<len;i++){
            pL = pL.getNext();
        }
        //PL和ps在同一起跑线上
        while (pL!=pS && pL!=null&&pS!=null){
            pL = pL.getNext();
            pS = pS.getNext();
        }
        if(pL == pS && pL!=null && pS!=null){
            return pL;
        }
        return null;
    }

10 . 单链表是否有环

    public boolean hasCycle(){
        Node fast = this.head;
        Node slow = this.head;
        while (fast!=null && fast.next!=null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow){
                return true;
            }
        }
        return false;
    }

11. 求链表入环的第一个结点,无环则返回null

  public Node detectCycle(){
        Node fast = this.head;
        Node slow = this.head;
        while (fast!=null && fast.next!=null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow){
                break;
            }

        }
        if(fast==null||fast.next==null){
            return null;
        }
        slow = this.head;
        while (fast!=slow){
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值