Explain the classic OJ questions of single linked list in detail

Keywords: Java Back-end

preface

This article is mainly about some classic related to linked lists in data structures OJ At the end of the paper, we also provide OJ The specific website of the question is for everyone to practice OJ I hope you can have a deeper understanding of the linked list. Finally, it is not easy to create. I hope you can give encouragement, praise, comment, exchange and study!

1. Delete all nodes in the linked list equal to the given value "val"

For example:
Input: head = [1,2,6,3,6], val = 6
Output: [1,2,3]

Graphic process:


After deletion

With the idea, the code is as follows:

    public nodelist deletion(int val){
        if (head==null)return null;
        nodelist cur=head;
        while (cur!=null){
            while(cur.next!=null&&cur.next.val==val){
                cur.next=cur.next.next;
            }
            cur=cur.next;
        }
        if(head.val==val){
            head=head.next;
        }
        return head;
    }

Second, reverse a single linked list

For example:
Input: head = [1,2,3,4,5]
Output: [5,4,3,2,1]



Code implementation

    public nodelist fanzhuang(){
        nodelist prve=null;
        nodelist cur=head.next;
        while (cur!=null){
            head.next=prve;
            prve=head;
            head=cur;
            cur=cur.next;
        }
        head.next=prve;
        return head;
    }

Three intermediate nodes

Given a non empty single linked list with head node, return the intermediate node of the linked list. If there are two intermediate nodes, the second intermediate node is returned.
For example:
head=[1,2,3,4,5] returns 3
head=[1,2,3,4] returns 3

Graphic analysis

Code implementation:

    //Intermediate node problem
    //Solution speed pointer
    public nodelist midnode(){
        nodelist fast=head;
        nodelist slow=head;
        while (fast!=null&&fast.next!=null){
            slow=slow.next;
            fast=fast.next.next;
        }
        return slow;
    }

For the analysis method of two nodes, you can draw your own drawing experience, and you can better understand this topic. Here we propose a variant. If there are two nodes, what should we do to return the first node?
The specific code implementation is as follows:

    public nodelist midnode(){
        nodelist fast=head;
        nodelist slow=head;
        while (fast!=null&&fast.next!=null){
            fast=fast.next.next;
            if (fast==null){
                return slow;
            }
            slow=slow.next;
           
        }
        return slow;
    }

The penultimate node of the four linked list


Specific code implementation:

//Find the penultimate node
    public nodelist node(int k){
        if (k<0||head==null)return null;
        nodelist slow=head;
        nodelist fast=head;
        while (k-1!=0){
            fast=fast.next;
            if (fast==null){//If it is out of range, fast should be null
                return null;
            }
            k--;
        }
        while (fast.next!=null){
            fast=fast.next;
            slow=slow.next;
        }
        return slow;
    }

V. merge ordered linked list

Merge the two ordered linked lists into a new ordered linked list and return. The new linked list is composed of all nodes of a given two linked lists.



For this problem, we can create a new node and string them. The specific implementation code is as follows:

    //Merge ordered list
    public static nodelist mergeTwoLists(nodelist head, nodelist head1) {
        nodelist newhead=new nodelist(-1);//Create a new node
        nodelist cur=newhead;
        while(head!=null&&head1!=null){
            if(head.val<head1.val){
                cur.next=head;
                cur=head;
                head=head.next;
            }else{
                cur.next=head1;
                cur=head1;
                head1=head1.next;
            }
        }
        if(head==null){
            cur.next=head1;
        }else{
            cur.next=head;
        }
        return newhead.next;
    }

Six linked list segmentation

Problem Description:

The existing head pointer ListNode head of a linked list gives a certain value of X, writes a piece of code, arranges all nodes less than x before other nodes, and cannot change the original data order, and returns the head pointer of the rearranged linked list.

Before splitting the linked list:

After split:

It should be noted here that we must first define a cur to traverse the linked list, and then use these four empty nodes to string them. It should be noted here that as, ae, bs, be, which we entered at the beginning, need to be discussed separately.

Attention to details:

1 if the value of x is appropriate, there may be no data in the first half of the split linked list, that is, as=null, then we must return bs (if the second half is also empty, it means an empty linked list)
2 after judging the previous one, we must make ae.next=bs, so as to link the split linked list
3 for the split linked list, we can't ensure that the last element must be in the second part or the first part. Then there will be a problem at this time, that is, the linked list has no tail, so we need to set be.next to null
Specific code implementation:

    //Segmentation of linked list
    public static nodelist spiltist(nodelist head,int x){
        nodelist as=null;
        nodelist ae=null;
        nodelist bs=null;
        nodelist be=null;
        nodelist cur=head;
        if (head==null)return null;
        while (cur!=null){
            if (cur.val<x){
                //First entry
                if (as==null){
                    as=cur;
                    ae=cur;
                }else{//Not the first time
                    ae.next=cur;
                    ae=ae.next;
                }
            }else{
                //First entry
                if (bs==null){
                    bs=cur;
                    be=cur;
                }else{//Not the first time
                    be.next=cur;
                    be=be.next;
                }
            }
            cur=cur.next;
        }
        if (as==null){//Judge whether there will be data in the first half
            return bs;
        }
        ae.next=bs;//Join the front and rear parts together
        if (bs!=null&&be.next!=null){//Judge whether be.next is null or not, and set it to null manually
            be.next=null;
        }
        return as;
    }

VII. Delete duplicate nodes

Problem Description:

In a sorted linked list, there are duplicate nodes. Please delete the duplicate nodes in the linked list. The duplicate nodes are not retained and the chain header pointer is returned. For example, the linked list 1 - > 2 - > 3 - > 3 - > 4 - > 4 - > 5 is 1 - > 2 - > 5 after processing

Before deletion:

After deletion:

Through the above two pictures, we can use a puppet node to string those non repeating nodes, and then return new.next, which will be the linked list we want to get.
Attention to details:
1. It is wrong to assume that newhead.next is the head at a glance, because if a linked list is {1, 1, 2, 3}, it can explain this wrong view
2 for the direct connection between the puppet node and the linked list, we can define a temp, let temp=newhead, when cur.val= When cur.next.val, let temp.next=cur
The specific code is as follows:

  //Delete duplicate nodes
    public nodelist delet(){
        nodelist newhead=new nodelist(1);
        nodelist cur=head;
        nodelist temp=newhead;
        while (cur!=null){
            if (cur.next!=null&&cur.val==cur.next.val){
                while(cur.next!=null&&cur.val==cur.next.val){//There are multiple duplicate values
                    cur=cur.next;
                }
                cur=cur.next;
            }else{
                temp.next=cur;
                cur=cur.next;
                temp=temp.next;
            }
        }
        if(temp.next!=null){
        temp.next=null;
        }

        return newhead.next;
    }

The last if statement should be mentioned here. In this code, if the linked list is {1, 2, 3, 3, 3}, if there is no if statement, the last repeated node cannot be deleted. According to the above code, what we want is that when cur=null, temp.next=null, so it is necessary for us to make such a judgment here.

Palindrome structure of eight linked list

For A linked list, please design an algorithm with time complexity of O(n) and additional space complexity of O(1) to judge whether it is palindrome structure. Given the header pointer A of A linked list, please return A bool value to represent whether it is A palindrome structure
For example: 1 - > 2 - > 2 - > 1
Return: true


One needs to use the fast and slow pointer to find the midpoint

Two reverse linked list


In the reverse linked list, we need to define a cur, let cur.next=slow, so as to complete the reversal of the next node where the current slow is located. We also need to go down. We need to define a curNext to record the next node of cur, but then a node cannot be found. We are moving slow=cur, so as to move slow back one bit. We are making cur=curNext, curNext=curNext.next (an if statement should be used here to determine whether curNext is null). Combined with the above, the ultimate goal is to reverse to the last node (that is, the position of slow should be on the last node). Then we must reverse more than one node, so we need a loop, Then the termination condition of this loop is cur= null
Three judge palindrome structure
From the picture after the inversion, if it is a palindrome structure, then if we walk back with slow and head at the same time, then head and slow will meet. In particular, the above situation is discussed for odd nodes. In fact, even nodes are the same, but when judging, it becomes head.next=slow. You can try to draw the specific figure yourself. In the code, I will write the total code of the two cases.
Code display

public class PalindromeList {
    public boolean chkPalindrome(ListNode head) {
        // write code here
        if(head==null||head.next==null)return false;
        //Find midpoint
        ListNode fast=head;
        ListNode slow=head;
        while(fast!=null&&fast.next!=null){
            fast=fast.next.next;
            slow=slow.next;
        }
        //Reverse linked list
        ListNode cur=slow.next;
        ListNode curNext=cur.next;
        while(cur!=null){
            cur.next=slow;
            slow=cur;
            cur=curNext;
            if(curNext!=null){
                curNext=curNext.next;
            }
        }
        //Judging palindrome structure
        while(head!=slow){
            if(head.val==slow.val){
                head=head.next;
                slow=slow.next;
                if(head.next==slow){
                    return true;
                }
            }else{
                return false;
            }
        }
        return true;
    }
}

Nine intersecting linked list

Title Description

Here are the head nodes headA and headB of the two single linked lists. Please find and return the starting node where the two single linked lists intersect. If the two linked lists do not have intersecting nodes, null is returned.


For intersecting nodes, we also adopt the method of fast and slow pointer, and set headA=slow and headB=fast. From the figure, we can see that B is longer than A, so we need to define an integer to represent the length difference between B and A, and let fast take this difference step more. Then fast and slow will go together, and then they will meet, and we will return to the meeting node

For the given linked list, it can also be this kind. It doesn't matter at this time. We can use an if to judge on the basis of the previous one. If B is longer, we can exchange the directions of fast and slow
The specific implementation code is as follows:

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode slow=headA;
        ListNode fast=headB;
        int lena = 0;
        int lenb = 0;
        while(slow!=null){
            lena++;
            slow=slow.next;
        }
        while(fast!=null){
            lenb++;
            fast=fast.next;
        }
        slow=headA;
        fast=headB;
        int c=lenb-lena;
        if(c<0){
            fast=headA;
            slow=headB;
            c=lena-lenb;
        }
        while(c!=0){
            fast=fast.next;
            c--;
        }
        while(fast!=slow){
            fast=fast.next;
            slow=slow.next;
        }
        return slow;
    }
}

X. judge whether there is a ring in the table


For the problem of whether the loop is formed, we use the fast and slow pointer to solve it. We let fast take two steps at a time and slow take one step at a time. Then slow and fast will eventually meet, but we dare not let fast go three times. If there are only two nodes, they will never meet
The specific code is as follows

public class Solution {
    public boolean hasCycle(ListNode head) {
        if(head==null||head.next==null)return false;
        ListNode fast=head.next;
        ListNode slow=head;
        while(fast!=null&&fast.next!=null){
            if(fast==slow){
                return true;
            }
            slow=slow.next;
            fast=fast.next.next;
        }
        return false;
    }
}

Eleven ring linked list II

Given a linked list, return the first node from the linked list into the ring. If the linked list is acyclic, null is returned.

As shown in the figure, we want to return the node 2. For this problem, we also use the fast and slow pointer to solve it
1 find the meeting point of fast and slow first
2 set one of fast and slow as the head node. If the two go together, they will go to the first node in the ring
Code implementation:

public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode slow=head;
        ListNode fast=head;
        while(fast!=null&&fast.next!=null){
            fast=fast.next.next;
            slow=slow.next;
            //If we meet in the ring
            if(fast==slow){
                break;
            }
        }
        //No meeting
        if(fast==null||fast.next==null){
            return null;
        }
        slow=head;
        while(slow!=fast){
            slow=slow.next;
            fast=fast.next;
        }
        return fast;
    }
}

OJ topic website

1 delete all nodes in the linked list equal to the given value val
2 reverse a single linked list
3 given a non empty single linked list with head node, return the intermediate node of the linked list. If there are two intermediate nodes, the second intermediate node is returned.
4 input a linked list and output the penultimate node in the linked list.
5 merge the two ordered linked lists into a new ordered linked list and return. The new linked list is composed of all nodes of a given two linked lists.
6 write code to divide the linked list into two parts based on the given value x, and all nodes less than X are arranged before nodes greater than or equal to X
7 in a sorted linked list, there are duplicate nodes. Please delete the duplicate nodes in the linked list. The duplicate nodes are not retained and the chain header pointer is returned.
Palindrome structure of linked list
9 input two linked lists and find their first common node.
10 given a linked list, judge whether there are links in the linked list
11 given a linked list, return the first node from the linked list into the ring. If the linked list is acyclic, null is returned

Posted by jtbaker on Mon, 22 Nov 2021 14:00:44 -0800