单链表OJ面试题(重点)

文章目录

  • OJ面试题
      • 1. 删除一个链表所有值为key的节点
      • 2. 反转一个单链表
      • 3. 找到单链表的中间节点
      • 4. 找到单链表的倒数第k个节点
      • 5. 合并两个有序链表
      • 6. 给定x为基准将链表分割成两部分,所有小于x的节点排在大于等于x的节点之前
      • 7. 删除有序链表中重复节点,不保留重复节点,返回头指针
      • 8 . 链表的回文结构
      • 9. 输入两个链表,找到相交节点
      • 10 . 单链表是否有环
      • 11. 求链表入环的第一个结点,无环则返回null

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

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

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

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

你可能感兴趣的:(数据结构)