【刷题 issue12】程序员代码面试指南 —— IT 名企算法与数据结构题目最优解

第二章 链表问题

2.2 在单链表和双链表中删除倒数第 K 个节点

【题目】

分别实现两个函数,一个可以删除单链表中倒数第 K 个节点,另一个可以删除双链表中倒数第 K 个节点。

【要求】

如果链表长度为 N,时间复杂度达到 O(N),额外空间复杂度达到 O(1)。

【难度】

士 ★☆☆☆

【题解】

对于单链表,如果链表为空或者 K<1,则参数是无效的,直接返回即可。否则让链表从头开始走到尾,每移动一步,就让 K 的值减一。当链表走到尾部,如果 K>0,则不用调整链表,因为链表没有倒数第 K 个节点;如果 K=0,则链表倒数第 K 个节点就是头节点,删去头节点即可;如果 K<0,则重新从头节点开始走,每走一步,就让 K 的值加一,当 K=0,移动到的节点就是倒数第 K 个节点的前一个节点,删去下一个节点即可。因为如果链表长度为 N ,要删除倒数第 K 个节点,倒数第 K 个节点的前一个节点就是第 N-K 个节点。在第一次遍历后,K 的值变为 K-N。第二次遍历时,K 的值不断加一直到等于 0,第二次遍历就会停到第 N-K 个节点的位置。

对于双链表,与单链表的处理方式一样,注意 last 指针的重连即可。

【实现】

  • RemoveSingleLinkedListLastKthNode
public class RemoveSingleLinkedListLastKthNode {

    private static class Node {
        public int value;
        public Node next;

        public Node(int value) {
            this.value = value;
        }
    }

    private Node head;

    public RemoveSingleLinkedListLastKthNode(int[] arr) {
        buildSingleLinkedList(arr);
    }

    private void buildSingleLinkedList(int[] arr) {
        if (arr != null && arr.length != 0) {
            Node preNode = this.head = new Node(arr[0]);
            for (int i = 1; i < arr.length; i++) {
                preNode = preNode.next = new Node(arr[i]);
            }
        }
    }

    public void removeSingleLinkedListLastKthNode(int lastKth) {
        if (this.head == null || lastKth < 1) {
            return;
        }
        Node curNode = this.head;
        while (curNode != null) {
            --lastKth;
            curNode = curNode.next;
        }
        /**
         *
         */
        if (lastKth == 0) {
            this.head = this.head.next;
        } else if (lastKth < 0) {
            curNode = this.head;
            while (++lastKth != 0) {
                curNode = curNode.next;
            }
            curNode.next = curNode.next.next;
        } else {
            // 超出范围
        }
    }

}
  • RemoveDoubleLinkedListLastKthNode.java
public class RemoveDoubleLinkedListLastKthNode {

    private static class Node {
        public int value;

        public Node last;
        public Node next;

        public Node(int value) {
            this.value = value;
        }
    }

    private Node head;

    public RemoveDoubleLinkedListLastKthNode(int[] arr) {
        buildDoubleLinkedList(arr);
    }

    private void buildDoubleLinkedList(int[] arr) {
        if (arr != null && arr.length != 0) {
            Node preNode = this.head = new Node(arr[0]);
            for (int i = 1; i < arr.length; i++) {
                preNode.next = new Node(arr[i]);
                preNode.next.last = preNode;
                preNode = preNode.next;
            }
        }

    }

    public void removeDoubleLinkedListLastKthNode(int lastKth) {
        if (this.head != null && lastKth >= 1) {
            Node curNode = this.head;
            while (curNode != null) {
                --lastKth;
                curNode = curNode.next;
            }
            if (lastKth == 0) {
                this.head = this.head.next;
                this.head.last = null;
            } else if (lastKth < 0) {
                curNode = this.head;
                while (++lastKth != 0) {
                    curNode = curNode.next;
                }
                curNode.next = curNode.next.next;
                if (curNode.next != null) {
                    curNode.next.last = curNode;
                }
            }
        }
    }

}
  • Test.java
public class Test {

    private RemoveSingleLinkedListLastKthNode singleLinkedList;
    private RemoveDoubleLinkedListLastKthNode doubleLinkedList;

    public Test(int[] arr) {
        this.singleLinkedList = new RemoveSingleLinkedListLastKthNode(arr);
        this.doubleLinkedList = new RemoveDoubleLinkedListLastKthNode(arr);
    }

    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5};
        Test test = new Test(arr);
        test.singleLinkedList.removeSingleLinkedListLastKthNode(3);
        test.doubleLinkedList.removeDoubleLinkedListLastKthNode(3);
    }

}
发布了147 篇原创文章 · 获赞 72 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/Pranuts_/article/details/100171535