The sword refers to the second edition of the offer interview question 22: the last k-th node in the linked list (java)

Topic description:
Input a linked list and output the k-th node from the bottom of the linked list. In order to conform to the habits of most people, this question starts counting from 1, that is, the tail node of the linked list is the last node. For example, a linked list has 6 nodes, starting from the head node, their values ​​are 1, 2, 3, 4, 5, 6 in order. The third-to-last node of this linked list is the node with the value 4.

Analysis:
In order to get the Kth node, the natural idea is to go to the end of the linked list first, and then backtrack K steps from the end. However, we can see from the definition of the node of the linked list that the linked list in this question is a singly linked list. The nodes of the singly linked list have only front-to-back pointers and no back-to-front pointers, so this idea does not work.
Since we can't traverse the linked list from the tail node, we still go back to the head node. Assuming that the entire linked list has N nodes, then the Kth node from the bottom is the n-k+1th node from the head node. Therefore, we can only go back n-k+1 steps from the head node. How to get the number of nodes n? This is not difficult, just traverse the linked list from the beginning, and add 1 to the counter every time you pass a node.
That is to say, we need to traverse the linked list twice, the first time we count the number of nodes in the linked list, and the second time we can find the kth node from the bottom. But when we explain this idea to the interviewer, he will tell us that the solution he expects only needs to traverse the linked list once.
In order to find the k-th last node by traversing the linked list only once, we can define two pointers. The first pointer traverses forward k-1 from the head pointer of the linked list. The second pointer remains stationary; starting at step k, the second pointer also starts traversing from the head pointer of the linked list. Since the distance between the two pointers is kept at k-1, when the first (going ahead) pointer reaches the end of the linked list, the second pointer is exactly the k-th last node.

code show as below:

/**
 * 链表中倒数第k个节点
 */
public class ReciprocalNumberKOfLink {

    public static ListNode findKthToTail(ListNode listHead, int k){
        //参数校验(判断链表是否存在、k是否大于0)
        if(listHead == null || k <= 0){
            return null;
        }

        ListNode ahead = listHead;          //前面的指针

        //先让ahead向前走k-1步
        for(int i = 1; i <= k-1; i++){
            if(ahead.next != null){
                ahead = ahead.next;
            }else{                          //当链表的长度小于k时,则返回null
                return null;
            }
        }
        ListNode behind = listHead;         //后面的指针

        while(ahead.next != null){
            ahead = ahead.next;
            behind = behind.next;
        }
        return behind;
    }

    public static void main(String[] args) {
        ListNode head = new ListNode();
        ListNode temp1 = new ListNode();
        ListNode temp2 = new ListNode();
        ListNode temp3 = new ListNode();
        ListNode temp4 = new ListNode();
        ListNode temp5 = new ListNode();
        ListNode temp6 = new ListNode();

        head.value=1;
        temp1.value=2;
        temp2.value=3;
        temp3.value=4;
        temp4.value=5;
        temp5.value=6;
        temp6.value=7;
        head.next=temp1;
        temp1.next=temp2;
        temp2.next=temp3;
        temp3.next=temp4;
        temp4.next=temp5;
        temp5.next=temp6;
        temp6.next=null;

        ListNode resultNode = findKthToTail(head, 2);
        if(resultNode != null){
            System.out.println(resultNode.value);
        }else{
            System.out.println("您输入的参数有误!");
        }
    }
}

//定义节点
class ListNode{
    int value;
    ListNode next;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325608982&siteId=291194637