删除链表中间节点和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
时间: 2024-10-12 20:11:28

删除链表中间节点和a/b处的节点的相关文章

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

删除链表的中间节点和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 等于

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

给定链表的表头节点head,实现删除链表的中间节点的函数 推展: 给定链表的头节点,整数a 和 整数 b,实现删除a/b处节点的函数 先来分析原问题, 长度1  直接返回 长度2 将头节点删除 长度3 删除第二个  长度4 删除第二个  长度5 删除第三个......长度每增加2 删除的节点就向后移动一个节点 如果要删除一个节点,则需要找到待删除节点的前一个节点 package TT; public class Test87 { public class Node{ public int val

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

题目:给定链表的头结点head,实现删除链表的中间节点的函数 例如: 1,不删除任何节点: 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 -->

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

问题描述: 给定链表的头结点head,实现删除链表的中间节点的函数: 例如: 不删除任何节点: 1-->2,删除节点1: 1-->2-->3,删除节点2 1-->2-->3-->4,删除节点2: 1-->2-->3-->4-->5,删除节点3: 分析及解题思路: 对于删除链表中的中间节点而言,当节点数增加2时,要删除的中间节点向后移一位.比如,首先链表中没有节点或节点为1个时,直接返回头结点:当节点数为2个时,直接返回head.next:对于三个

删除链表中的节点

1.删除链表中等于给定值 val 的所有节点. class Solution { public: ListNode* removeElements(ListNode* head, int val) { ListNode*newHead=new ListNode(-1); ListNode*pre=newHead; pre->next=head; while(pre->next!=NULL){ ListNode*cur=pre->next; if(cur->val==val){ pr

LintCode Python 简单级题目 452.删除链表中的元素

原题描述: 删除链表中等于给定值val的所有节点. 您在真实的面试中是否遇到过这个题? Yes 样例 给出链表 1->2->3->3->4->5->3, 和 val = 3, 你需要返回删除3之后的链表:1->2->4->5. 标签 链表 题目分析: 删除链表中等于给定值val的所有节点. 遍历链表,找到其中next.val等于val的节点,删除. 注意的地方就是可能链表中的所有元素val都等于val,循环的开始需要从表头开始删除,需要新增一个头节点.

LintCode 删除链表中的元素

删除链表中等于给定值val的所有节点. 样例 给出链表 1->2->3->3->4->5->3, 和 val = 3, 你需要返回删除3之后的链表:1->2->4->5 参考@GrandYang  ... 方法1:引入dummy class Solution { public: /** * @param head a ListNode * @param val an integer * @return a ListNode */ ListNode *r

删除链表的倒数第N个节点

给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点. 示例: 给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二个节点后,链表变为 1->2->3->5. 一种方法是先计算链表的长度N,然后定位到第(N-n)个节点,删除节点(N-n+1)也即(倒数第n个节点) 代码如下: public static ListNode removeNthFromEnd(ListNode head, int n) { // 新建一个节点te

剑指Offer之在O(1)时间删除链表节点

题目描述 给定单向链表的头指针和一个节点指针,定义一个函数在O(1)时间删除该节点. 解题思路 在单向链表中删除一个节点,最常规的做法无疑是从链表的头结点开始,顺序的遍历查找要删除的节点,并在链表中删除该节点.这种思路由于需要顺序查找,时间复杂度自然就是$O(n)$了. 之所以需要从头开始查找,是因为我们需要得到将删除的节点的前面一个节点.在单向链表中,节点中没有指向前一个节点的指针,所以只好从链表的头结点开始顺序查找.那是不是一定需要得到被删除的节点的前一个节点呢?答案是否定的.我们可以很方便