Interview questions in linked list
1, [Leetcode] 203 remove linked list elements
203 remove linked list elements
[Title Description]: give you a head node of the linked list and an integer val. please delete all nodes in the linked list that meet Node.val == val and return a new head node
This problem is the same as the removeAllKey method for deleting all nodes with key value in the single linked list.
/** * Definition for singlylinked list. * public class ListNode { * int val; * ListNode next; * ListNode() {} * ListNode(int val) { this.val = val; } * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public ListNode removeElements(ListNode head, int val) { //The removeElements function has given the head node head, so you don't need to add this if(head == null){ return null ; } ListNode prev=head; ListNode cur=head.next; while(cur!=null){ if(cur.val==val){ prev.next=cur.next; cur=cur.next; }else{ prev=cur; cur=cur.next; } } if(head.val==val){ head=head.next; } return head;//Returns the new header node //The returned ListNode is essentially the header node after deleting all val, and returns the deleted header } }
2, [Leetcode] 206 reverse linked list (reverse linked list)
[Title Description]: give you the head node of the single linked list. Please reverse the linked list and return the reversed linked list.
The logic analysis is as follows:
First, we draw a single linked list and make logical analysis according to the single linked list.
To reverse a single linked list is to reverse a single linked list. Is the reverse linked list the reverse data? Please think
Is this the final result we want?
Obviously, it's not the result we want. Why?
Because it's crossed? Hehe, of course not. To solve this problem, we must be clear that reverse linked list is not reverse data, reverse is not reverse data, and the real requirement of reverse is that the node itself should also be reverse.
How did he reverse it? Maybe we can think about this by head inserting
Define a cur to represent the current node to be reversed, and then define a curNext to record its next node. Use curNext to record the next to modify the cur of the current node
==Question: = = why define newHead?
newHead is the latest head node, but in the whole process, newHead acts as the precursor of each node.
What does that mean?
Because the logic of the above inversion is similar to that of header interpolation, newHead can be regarded as the precursor prev of each node to make reasonable use of the nature of header interpolation.
The analysis is shown in the figure:
The complete code is as follows:
/** * Definition for singlylinked list. * public class ListNode { * int val; * ListNode next; * ListNode() {} * ListNode(int val) { this.val = val; } * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public ListNode reverseList(ListNode head) { // if(head==null) / / when the single linked list is empty // return null;// If the single linked list is empty, head can also be returned // if(head.next==null) / / the first node is empty // return head; if(head==null  head.next==null) return head; ListNode cur=head; ListNode newHead=null; while(cur!=null){//cur is not equal to null, indicating that the linked list has not been traversed ListNode curNext=cur.next; cur.next=newHead; newHead=cur; cur=curNext; } return newHead; } }
3, [Leetcode] 876 intermediate node of linked list
876 intermediate node of linked list
[Title Description]: given a non empty single linked list whose head node is head, return the intermediate node of the linked list.
If there are two intermediate nodes, the second intermediate node is returned.
Requirement: only go through the linked list once to find the intermediate node
If we use the length method to solve this problem, we need to traverse the linked list twice to complete it. We require that we can find the intermediate node only by walking through the linked list once, so we can use another method (i.e. fast and slow node points).
Drawing analysis logic:
Summary: when the number of nodes is odd, fast takes two steps and slow takes one step. When fast goes to fast.next is null, slow goes to the intermediate node.
Summary: when the number of nodes is even, fast takes two steps and slow takes one step. When fast goes to fast and fast is null, slow goes to the intermediate node.
/** * Definition for singlylinked list. * public class ListNode { * int val; * ListNode next; * ListNode() {} * ListNode(int val) { this.val = val; } * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public ListNode middleNode(ListNode head) { if(head==null){//Judge whether the head node is null. If it is null, there will be no intermediate node, and the head is returned return head; } ListNode fast=head; ListNode slow=head; while(fast!=null && fast.next!=null){ fast=fast.next.next;//fast takes two steps slow=slow.next;//slow step } return slow; } }
4, [sword finger offer] the penultimate node in the lin k ed list
The penultimate node in the lin k ed list
[Title Description]: Enter a linked list , output the penultimate node in the lin k ed list.
len  the penultimate node to find = the number of steps to take. After walking, you will find the penultimate node in the linked list
lenk = number of steps to take, as shown in the figure:
This method also needs to traverse the linked list twice, which is not the best consideration.
We can also consider trying to traverse the list once to solve the problem.
Let the fast pointer (Reference) go one step first, then fast reference fast and slow reference slow, and then go at the same time. When fast goes to fast.nex is null, the node referred to by slow is the penultimate node.
/* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } }*/ public class Solution { public ListNode FindKthToTail(ListNode head,int k) { if(head==null){ return null; } if(k<=0){//If k is illegal return null; } ListNode fast=head; ListNode slow=head; //Let fast go k1 first while(k1!=0){ if(fast.next!=null){//If the number of nodes is less than k,k is illegal fast=fast.next; k; }else{ return null; } } //After k1, fast and slow go together while(fast.next!=null){ fast=fast.next; slow=slow.next; } return slow; } }
5, [Leetcode] 21 merge two ordered linked lists
21 merge two ordered linked lists
[Title Description]: merge two ascending linked lists into a new ascending linked list and return. The new linked list is composed of all nodes of a given two linked lists.
Logical analysis:

Define a virtual node newHead. The initial value is null. It is always the head node of the new linked list;

As long as the two references of headA and headB are not empty, compare their data values respectively. Whoever is young will be concatenated behind the virtual node newHead. The newHead cannot move. Define a TMP at the newHead node, make tmp.next equal to the current concatenated node each time, and then make TMP equal to the next node of TMP (TMP points to the next node of TMP).
/** * Definition for singlylinked list. * public class ListNode { * int val; * ListNode next; * ListNode() {} * ListNode(int val) { this.val = val; } * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { public ListNode mergeTwoLists(ListNode headA, ListNode headB) { //If one of the two linked lists is empty and the other is not empty, the non empty linked list is returned if(headA==null){ return headB; } if(headB==null){ return headA; } //If both linked lists are empty, null is returned if(headA==null && headB==null){ return null; } ListNode newHead=new ListNode(1); ListNode tmp=newHead; //If both linked lists are not empty, compare the val values of the two linked lists while(headA!=null && headB!=null){ if(headA.val < headB.val){ tmp.next=headA; headA=headA.next;//Head a, go back }else{ tmp.next=headB; headB=headB.next;//head, go back } tmp=tmp.next;//After the change, tmp also walked back } if(headA==null){ tmp.next= headB; } if(headB==null){ tmp.next= headA; } return newHead.next;//newHead is a virtual head node, while the real node in the linked list does not take the lead } }
6, [niuke.com  program interview dictionary] CM 11 linked list segmentation
CM 11 linked list segmentation
[Title Description]: there is a header pointer ListNode* pHead of a linked list. Given a certain value of X, write a code to rank all nodes less than x before other nodes, and the original data order cannot be changed. Return the header pointer of the rearranged linked list.
Consider two questions first:
1. Judge how to deal with those larger than the fixed value and those smaller than the fixed value?
2. How to ensure that the data sequence remains unchanged after comparison?
Problem solving ideas:

Tail interpolation

Write a code less than the fixed value x in the original order, and then write a code greater than the fixed value x in the original order, and splice the codes at both ends.

Define the beginning less than x as bs (beginstart), the end less than x as be(beginend), the beginning greater than or equal to X as, and the end greater than or equal to X as ae. Finally, connect be and as.
As shown in the figure:
The simple point is:
The logic analysis is shown in the figure below:
**Note: * * the next of the last node in the linked list is not null, which will lead to an endless loop of code, or the bs itself may be null
Example of linked list partition code:
import java.util.*; /* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } }*/ public class Partition { public ListNode partition(ListNode pHead, int x) { // write code here ListNode cur=pHead; ListNode bs=null; ListNode be=null; ListNode as=null; ListNode ae=null; while(cur!=null){//It indicates that the linked list has not been traversed if(cur.val<x){ //Part I first insertion if(bs==null){ bs=cur; be=cur; }else{ be.next=cur; be=be.next; } }else{ //Part II first insertion if(as==null) { as = cur; ae = cur; }else{ ae.next=cur; ae=ae.next; } } cur=cur.next; } if(bs==null){//Note that the first part is null, that is, there is no data less than x, then the next paragraph is returned return as; } //bs!=null be.next=as;//If the front of the first part is not null, the end of the first part and the beginning of the second part are spliced together if(as!=null){ ae.next=null; } return bs; } }
7, [sword finger offer] JZ56 deletes duplicate nodes in the linked list
JZ56 delete duplicate nodes in linked list
[Title Description]: there are duplicate nodes in a sorted linked list. 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.
Logical analysis: because the nodes are already arranged in order, the same nodes must be arranged together.
1. Set a new virtual node (puppet node) newHead to identify the head node of the new node. cur is used to traverse the original linked list.
2. If cur.val=cur.next.val indicates that the first node is duplicate. If it is not equal to, it indicates that the first node is not duplicate. Put this node behind the newHead. Because the newHead cannot move, define another tmpH for it, so that the next of tmpH is equal to the current cur, and then let tmp=tmp.next go back and cur=cur.next go back.
Delete duplicate node codes in the linked list as follows:
/* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } } */ public class Solution { public ListNode deleteDuplication(ListNode pHead) { ListNode newHead=new ListNode(1);//Define a virtual node newHead ListNode tmp=newHead; ListNode cur=pHead; while(cur!=null){ //cur.next!=null: judge whether there is only one node or tail node if(cur.next!=null && cur.val==cur.next.val){ //In the process of cur, the remaining data may be the same, so cur.next needs to be added= Null this condition //Otherwise, a null pointer exception will occur while(cur.next!=null && cur.val==cur.next.val){ cur=cur.next; } cur=cur.next;//If cur takes one more step, it can skip the previous repeated node. }else{ tmp.next=cur; tmp=tmp.next;//String the nodes together and tmp move back cur=cur.next;//cur, go back } } tmp.next=null;//Set manually to prevent the last node from being repeated and avoid dead cycle return newHead.next; } }
8, [online programming of 2016 school enrollment real questions] palindrome structure of OR36 linked list
Palindrome structure of OR36 linked list (frequently asked questions with headline and byte jumping)
[Title Description]: 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. Ensure that the length of the linked list is less than or equal to 900.
Test example:
1>2>2>1 return: true
Question 1: if you define two references cur1 and cur2, cur1 goes back from the beginning and cur2 goes forward from the end? Is this method feasible?
It's not feasible because it's a oneway linked list. We don't know what the previous node of cur2 is.
solve the problem:
First find the intermediate node of the linked list and reverse the linked list after the intermediate node.
Logical analysis:
1. How to find the middle node of the linked list?
 Define a fast and slow. Let fast take two steps at a time and slow take one step at a time. When fast.next is null, slow is the intermediate node of the linked list.
2. After the intermediate node is found, how to reverse it?
 The intermediate node slow is equivalent to the precursor of the latter node. The latter node is defined as cur, and the node pointed to by fast is defined as curNext. It is used to record the value of cur.next, so that the value of cur.next is equal to the value of slow. Slow points to cur,cur=curNext,cur is not equal to null, and curNext moves backward, that is, curNext=cur.next;
3. After reversing, judge one by one. Head moves back and slow moves forward until they meet. The principle of judgment is that if the data values of head and slow are different, it will directly return to false.
The drawing analysis is as follows:
Palindrome structure code is as follows:
import java.util.*; /* public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } }*/ public class PalindromeList { public boolean chkPalindrome(ListNode A) { if(A==null){ return true; } if(A.next==null){ //There is only one node, and one node is also a palindrome node return true; } //1. Find intermediate nodes ListNode slow = A; ListNode fast = A; while (fast != null && fast.next != null) {//Divided into odd and even cases fast = fast.next.next; slow = slow.next; } //The node pointed to by slow is the intermediate node of the linked list. //2. Flip ListNode cur = slow.next; while (cur != null) {//Only cur is not equal to null, can we continue to go down ListNode curNext = cur.next; cur.next = slow; slow = cur; cur = curNext; } ///After reversing, slow points to the last node //3. Judge the palindrome to see if the results of slow and head meet are equal while (slow != A) { if (slow.val != A.val) { return false; } if(A.next==slow){//If the linked list has even nodes (I don't understand. 1:29:00) return true; } A = A.next; slow = slow.next; } return true; } }
9, [Leetcode] 141. Circular linked list
141. Circular linked list
[Title Description]: given a linked list, judge whether there are links in the linked list. Returns true if there are links in the linked list. Otherwise, false is returned.
If there is a node in the linked list that can be reached again by continuously tracking the next pointer, there is a ring in the linked list. In order to represent the rings in a given list, we use the integer pos to represent the position where the tail of the list is connected to the list (the index starts from 0). If pos is  1, there is no ring in the linked list. Note: pos is not passed as a parameter, but only to identify the actual situation of the linked list.
What is a ring?
In human words, if the last node of the linked list is equal to a node in front of it, it means that there is a ring. If there is a ring in the linked list, return true. Otherwise, return false .
**Logical analysis: * * define a fast and then a slow. Fast takes two steps and slow takes one step. After each slow, see whether fast and slow meet. If they meet, it indicates that the linked list has rings. As shown in the figure:
Question 1: can fast take two steps at a time, three or four steps at a time?
No, because you may not meet, or you may meet after a long time.
Question 2: why can we meet two steps at a time?
Because fast takes two steps and slow takes one step, the difference between them is the smallest. Fast is always one step faster than slow, and it is also faster to catch up. If fast takes three or four steps, it may take a long time to catch up.
The ring list I code is as follows:
/** * Definition for singlylinked list. * class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public boolean hasCycle(ListNode head) { ListNode fast=head; ListNode slow=head; while(fast!=null && fast.next!=null){//There are even or odd numbers fast= Null is used to judge even nodes, fast. Next= null //Used to judge odd nodes //If none is null fast=fast.next.next; slow=slow.next; //Every time you walk, you have to see if fast and slow meet if(slow==fast){//Return true if encounter return true; } } return false;//false is returned whenever any of them is null } }
10, [Leetcode] 142. Circular linked list II (find the entry point of the linked list ring)
142. Ring linked list II (find the entry point of the linked list ring)
[Title Description]: given a linked list, return to the first node of the linked list. If the linked list is acyclic, null is returned.
In order to represent the rings in a given list, we use the integer pos to represent the position where the tail of the list is connected to the list (the index starts from 0). If pos is  1, there is no ring in the linked list. Note that pos is only used to identify the ring and is not passed to the function as an argument.
Note: it is not allowed to modify the given linked list.
Set the distance from the start to the entry point as X, the distance from the entry point to the meeting point as Y, and the length of the ring as C
Under normal circumstances (walking around):
The slow distance is X+CY, and the fast distance is X+C+CY
The fast speed is twice the slow speed, which means that the fast distance is twice the slow distance.
That is, 2 (X+CY) = X+C+CY
Under special circumstances (in case of multiple turns):
The slow distance is X+CY, and the fast distance is X+NC+CY
The fast speed is twice the slow speed, which means that the fast distance is twice the slow distance.
That is, 2 (X+CY) = X+NC+CY
Drawing analysis:
Ring linked list II code example:
/** * Definition for singlylinked list. * class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public ListNode detectCycle(ListNode head) { ListNode fast=head; ListNode slow=head; while(fast!=null && fast.next!=null){//There are even or odd numbers fast= Null is used to judge even nodes, fast. Next= null //Used to judge odd nodes //If none is null fast=fast.next.next; slow=slow.next; //It depends on whether fast and slow are finished every time if(slow==fast){//Return true if encounter break; } } if(fast==null  fast.next==null){//If it is empty, it means there is no ring, and if there is no bad, it returns null return null; } //If the loop execution ends, it indicates that there is a ring. If there is a ring, slow and fast meet slow=head; //Move the reference slow to the front while(fast!=slow){ fast=fast.next; slow=slow.next; } return slow; } }
11, [Leetcode] 160 intersecting linked list
160 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 two linked lists have no intersection, null is returned.
Question: what kind of situation is the intersection of two single linked lists?
It's a Y shape, similar to this
Example 1:
Input: intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
Output: Intersected at '8'
Explanation: the value of intersection node is 8 (note that if two linked lists intersect, it cannot be 0).
Starting from their respective headers, linked list A is [4,1,8,4,5], and linked list B is [5,0,1,8,4,5].
In A, there are 2 nodes before the intersection node; In B, there are 3 nodes before the intersection node.
There are three ideas:
1. Find the length of two single linked lists
2. Calculate the difference between the lengths of two single linked lists
3. Let the long single linked list go first
==Question: = = there may be two single linked lists with different lengths. How do you know which is longer and which is shorter?
Define a single linked list with pl pointing to length
Define a single linked list with ps pointing to short
Assume default first
pl=headA
ps=headB
Then define a lenA, lenB, len = lenA lenB
len=lenAlenB
If Lena lenb < 0, change the original default value, that is, pl=headB,ps=headA. After changing, let len = lenb Lena;
If Lena lenb > 0, it doesn't matter. It means that the original default is correct, and the len value must be a positive number.
The code under IDEA is written as follows:
public class TestMyLinkedList { //Code for intersecting two separate single linked lists public static void createCut(ListNode headA,ListNode headB){ headA.next=headB.next.next; } public static ListNode getIntersectionNode(ListNode headA, ListNode headB) { //1. Find the length and take the step of difference int lenA=0; int lenB=0; ListNode pl=headA; ListNode ps=headB; //Find length while(pl!=null){ lenA++; pl=pl.next; } while (ps!=null){ lenB++; ps=ps.next; } int len=lenAlenB; if(len<0){ pl=headB; ps=headA; len=lenBlenA; } //pl must point to the longest single linked list for(int i=0;i<len;i++){ pl=pl.next; } //2. ps and pl must be on the same starting line while(ps!=pl && pl!=null && ps!=null){ ps=ps.next; pl=pl.next; } if(pl==ps && pl!=null){//The code here indicates that pl and ps have met return pl; } return null; } public static void main(String[] args) { MyLinkedList myLinkedList = new MyLinkedList();//Get a single linked list object first myLinkedList.addLast(10); myLinkedList.addLast(16); myLinkedList.addLast(23); myLinkedList.addLast(46); myLinkedList.addLast(37); myLinkedList.addLast(12); myLinkedList.addLast(19); myLinkedList.display(); MyLinkedList myLinkedList1 = new MyLinkedList();//Get a single linked list object first myLinkedList1.addLast(1); myLinkedList1.addLast(3); myLinkedList1.addLast(5); myLinkedList1.addLast(7); myLinkedList1.addLast(9); myLinkedList1.addLast(13); myLinkedList1.display(); createCut(myLinkedList.head,myLinkedList1.head);//call ListNode ret=getIntersectionNode(myLinkedList.head,myLinkedList1.head); System.out.println(ret.data);
The Leetcode code is written as follows:
/** * Definition for singlylinked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public ListNode getIntersectionNode(ListNode headA, ListNode headB) { //1. Find the length and take the step of difference int lenA=0; int lenB=0; ListNode pl=headA; ListNode ps=headB; //Find length while(pl!=null){ lenA++; pl=pl.next; } while (ps!=null){ lenB++; ps=ps.next; } pl=headA; ps=headB; int len=lenAlenB; if(len<0){ pl=headB; ps=headA; len=lenBlenA; } //pl must point to the longest single linked list for(int i=0;i<len;i++){//Take the difference step pl=pl.next; } //2. ps and pl must be on the same starting line while(ps!=pl ){// && pl!=null && ps!=null ps=ps.next; pl=pl.next; } if(pl!=null){//When the code comes here, it means that pl and ps meet. pl = = ps&& return pl; } return null; } }