zoukankan      html  css  js  c++  java
  • 删除链表中间节点和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
  • 相关阅读:
    Unity3d修炼之路:游戏开发中,3d数学知识的练习【1】(不断更新.......)
    Codeforces 463C Gargari and Bishops 题解
    kettle入门(七) 之kettle增量方案(一)全量比对取增量-依据唯一标示
    cpp学习笔记 1一个简单的小程序以及一些的知识点
    POJ 1321-棋盘问题(DFS)
    偶遇 smon 进程cpu 开销高异常分析
    Android 虚线切割线
    magento安装wordpress
    分组password算法
    Android_编程规范与经常使用技巧
  • 原文地址:https://www.cnblogs.com/xiyuan2016/p/6862629.html
Copyright © 2011-2022 走看看