删除链表中间节点和a/b处的节点

Posted 数据科学工作加油站

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了删除链表中间节点和a/b处的节点相关的知识,希望对你有一定的参考价值。

[题目]:

  给定链表的头节点 head,实现删除链表的中间节点的函数。

  例如:

  步删除任何节点;

  1->2,删除节点1;

  1->2->3,删除节点2;

  1->2->3->4,删除节点2;

  1->2->3->4-5,删除节点3;

[进阶]:

  给定链表的头节点 head、整数 a 和 b,实现删除位于 a/b 处节点的函数。

  例如:

  链表:1->2->3->4->5,假设 a/b 的值为 r。

  如果 r = 0,不删除任何节点;

  如果 r 在区间 (0,1/5] 上,删除节点 1;

  如果 r 在区间 (1/5,2/5] 上,删除节点 2;

  如果 r 在区间 (2/5,3/5] 上,删除节点 3;

  如果 r 在区间 (3/5,4/5] 上,删除节点 4;

  如果 r 在区间 (4/5,1] 上,删除节点 5;

  如果 r 大于 1,不删除任何节点。

[思路]:

  对于删除中间节点的问题:根据题意可知,链表长度每增加2(3,5,7......),要删除的节点就后移一个节点。设定两个指针,一个指针每次向前走一步,另一个向前走两步。

  对于删除 a/b 节点问题:((double) (a * n)) / (double) b  向上取整之后的整数值代表该删除的节点是第几个节点。

    仔细体会链表里的思想,还是蛮不错的。

public class Problem03_RemoveNodeByRatio {
    
    public static class Node {
        public int value;
        public Node next;
    
        public Node(int data) {
            this.value = data;
        }
    }
    
// 删除中间节点
    public static Node removeMidNode(Node head){
        if (head == null || head.next == null) {
            return head;
        }
        if (head.next.next == null) {
            return head.next;        
        }
        Node pre = head;
        Node cur = head.next.next;
        while (cur.next != null && cur.next.next != null) {
            pre = pre.next;
            cur = cur.next.next;
        }
        pre.next = pre.next.next;
        return head;
    }
    // 删除a/b节点
    public static Node removeByRatio(Node head, int a, int b) {
        if (a < 1 || a > b){
            return  head;
        }
        int n = 0;
        Node cur = head;
        while(cur != null) {
            n++;
            cur = cur.next;            
        }
        // 去(a*n)/b  向上取整
        n = (int) Math.ceil(((double) (a * n) )/ (double) b);
        if ( n == 1) {
            head = head.next;
        }
        if (n > 1) {
            cur = head;
            while ( --n != 1 ){
                cur = cur.next;
            }
            cur.next = cur.next.next;
        }
        return head;
    }
    
    public static void printLinkedList(Node head) {
        System.out.print("Linked List: ");
        while (head != null) {
            System.out.print(head.value + " ");
            head = head.next;
        }
        System.out.println();
    }
    
    public static void main(String[] args) {
        Node head = new Node(1);
        head.next = new Node(2);
        head.next.next = new Node(3);
        head.next.next.next = new Node(4);
        head.next.next.next.next = new Node(5);
        head.next.next.next.next.next = new Node(6);

        printLinkedList(head);
        head = removeMidNode(head);
        printLinkedList(head);
        head = removeByRatio(head, 2, 5);
        printLinkedList(head);
        head = removeByRatio(head, 1, 3);
        printLinkedList(head);
        
    }

}

运行结果:

Linked List: 1 4 5 6 
Linked List: 1 5 6

以上是关于删除链表中间节点和a/b处的节点的主要内容,如果未能解决你的问题,请参考以下文章

删除链表中间节点和a/b处的节点

算法总结之 删除链表的中间节点和a/b处的节点(链表中间节点的重要思想)

2.3 删除链表的中间节点和a/b处的节点

[算法]删除链表的中间节点

LeetCode 2095. 删除链表的中间节点

LeetCode刷题(144)~删除中间节点