链表问题----删除链表的中间节点和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 等于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,不删除任何节点
package com.test; import com.tset.ListNode; /** * Created by Demrystv. */ public class RemoveListNode { // 针对普通问题,采用的方法是找规律,当元素个数大于3时,链表长度每增加2,要删除的节点就要后移一个节点 public ListNode removeMiddle(ListNode head){ // 针对的是没有元素或者只有一个元素 if (head == null || head.next == null){ return null; } // 针对的是只有两个元素 if (head.next.next == null){ return head.next; } // 针对的是三个及三个以上元素,这时符合规律 ListNode pre = head; ListNode cur = head.next.next; while (pre.next != null && cur.next.next != null){ pre = pre.next; cur = cur.next.next; } pre.next = pre.next.next; return head; } // 针对进阶问题,主要是找到n,即要删除的元素的位置 public ListNode removeByRatio(ListNode head, int a ,int b){ if (a < 1 || a > b){ return head; } // 求链表的长度 int n = 0; ListNode cur = head; while (cur != null){ n++; cur = cur.next; } // n表示要删除的节点是第几个节点,可以举例证明,也可以通过举例来推导 n = (int) Math.ceil((double)(a * n) / (double) b); // 其原理类似于删除倒数第K 个节点 if (n == 1){ return head.next; } if (n > 1){ cur = head; while (--n != 0){ cur = cur.next; } cur.next = cur.next.next; } return head; } }