剑指Offer笔记—— 数值的整数次方 在O(1)时间删除链表结点

面试题11:数值的整数次方

题目大致为:
    实现函数double power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。
思路:
    可以考虑对指数折半,这样只需要计算一半的值,若指数是奇数,则-1再折半,否则直接折半。
Java实现
[java]  view plain  copy
  1. package org.algorithm.pointtooffer;  
  2.   
  3. /** 
  4.  * 面试题11:数值的整数次方 
  5.  *  
  6.  * @author dell 
  7.  *  
  8.  */  
  9. public class Item11 {  
  10.     public static void main(String args[]) {  
  11.         int base = 2;  
  12.         int exponent_1 = 9;  
  13.         int exponent_2 = 10;  
  14.         System.out.println("当exponent为奇数:" + power(base, exponent_1));  
  15.         System.out.println("当exponent为偶数:" + power(base, exponent_2));  
  16.     }  
  17.   
  18.     /** 
  19.      * 整数次方 
  20.      *  
  21.      * @param base底 
  22.      * @param exponent指数 
  23.      * @return 
  24.      */  
  25.     public static double power(double base, int exponent) {  
  26.         if (exponent == 0) {  
  27.             return 1;  
  28.         }  
  29.   
  30.         if (exponent == 1) {  
  31.             return base;  
  32.         }  
  33.         if (exponent >> 1 == 0) {// 偶数  
  34.             int exponent_1 = exponent >> 1;  
  35.             double tmp = power(base, exponent_1);  
  36.             return tmp * tmp;  
  37.         } else {// 非偶数  
  38.             int exponent_2 = exponent - 1;// -1后就是偶数  
  39.             double tmp = power(base, exponent_2);  
  40.             return tmp * base;// 最后还有先开始减掉的一个base  
  41.         }  
  42.     }  
  43. }  

面试题12:打印1到最大的n位数

面试题13:在O(1)时间删除链表结点

题目大致为:
    给定单向链表的头指针和一个结点指针,定义一个函数在 O(1) 时间删除该结点。
思路:
    想要在 O(1) 时间内删除链表的指定结点,要遍历的话得 O(n) ,则肯定不能遍历。若是要删除的结点不是尾结点,那么可以将后面的那个值复制到该指针处,并将后面指针所指空间删除,用复制+删除后面的实现删除,时间复杂度为 O(1) 。对于尾结点,需要遍历,那么时间复杂度是 O(n) ,但是总的时间复杂度为 [(n-1)*O(1)+O(n)]/n ,结果是 O(1)
链表结构:
[java]  view plain  copy
  1. package org.algorithm.pointtooffer;  
  2.   
  3. /** 
  4.  * 链表的节点 
  5.  *  
  6.  * @author dell 
  7.  *  
  8.  */  
  9. public class ListNode {  
  10.     private int value;  
  11.     private ListNode next;  
  12.   
  13.     public ListNode(int value) {  
  14.         this.value = value;  
  15.     }  
  16.   
  17.     public ListNode(int value, ListNode next) {  
  18.         this.value = value;  
  19.         this.next = next;  
  20.     }  
  21.   
  22.     public void setValue(int value) {  
  23.         this.value = value;  
  24.     }  
  25.   
  26.     public void setNext(ListNode next) {  
  27.         this.next = next;  
  28.     }  
  29.   
  30.     public int getValue() {  
  31.         return this.value;  
  32.     }  
  33.   
  34.     public ListNode getNext() {  
  35.         return this.next;  
  36.     }  
  37.   
  38. }  

Java实现
[java]  view plain  copy
  1. package org.algorithm.pointtooffer;  
  2.   
  3. /** 
  4.  * 面试题13:在O(1)时间删除链表的节点 
  5.  *  
  6.  * @author dell 
  7.  *  
  8.  */  
  9. public class Item13 {  
  10.     public static void main(String args[]) {  
  11.         // 构建链表  
  12.         ListNode head = new ListNode(1);  
  13.         ListNode node_2 = new ListNode(2);  
  14.         ListNode node_3 = new ListNode(3);  
  15.         ListNode node_4 = new ListNode(4);  
  16.         ListNode node_5 = new ListNode(5);  
  17.         ListNode node_6 = new ListNode(6);  
  18.         ListNode node_7 = new ListNode(7);  
  19.         head.setNext(node_2);  
  20.         node_2.setNext(node_3);  
  21.         node_3.setNext(node_4);  
  22.         node_4.setNext(node_5);  
  23.         node_5.setNext(node_6);  
  24.         node_6.setNext(node_7);  
  25.         node_7.setNext(null);  
  26.   
  27.         // 输出原始链表  
  28.         System.out.println("原始链表:");  
  29.         printList(head);  
  30.         System.out.println("----------------");  
  31.   
  32.         // 删除结点node_3  
  33.         deleteNode(head, node_3);  
  34.         System.out.println("删除node_3后链表:");  
  35.         printList(head);  
  36.         System.out.println("----------------");  
  37.   
  38.         // 删除结点head  
  39.         deleteNode(head, head);  
  40.         System.out.println("删除head后链表:");  
  41.         printList(head);  
  42.         System.out.println("----------------");  
  43.     }  
  44.   
  45.     /** 
  46.      * 狸猫换太子删除结点 
  47.      *  
  48.      * @param head头指针 
  49.      * @param toBeDeleted要删除的指针 
  50.      */  
  51.     public static void deleteNode(ListNode head, ListNode toBeDeleted) {  
  52.         if (head == null || toBeDeleted == null) {  
  53.             return;  
  54.         }  
  55.   
  56.         // 找到要删除的节点的下一个节点  
  57.         if (toBeDeleted.getNext() != null) {  
  58.             ListNode p = toBeDeleted.getNext();// p为toBeDeleted的下一个节点  
  59.             toBeDeleted.setValue(p.getValue());  
  60.             // 删除p节点  
  61.             toBeDeleted.setNext(p.getNext());  
  62.         } else if (head == toBeDeleted) {  
  63.             // 如果头结点就是要删除的节点  
  64.             head = null;  
  65.         } else {  
  66.             // 删除尾节点  
  67.             ListNode currentNode = head;// 用于遍历链表  
  68.             while (currentNode.getNext() != toBeDeleted) {  
  69.                 currentNode = currentNode.getNext();  
  70.             }  
  71.             currentNode.setNext(null);  
  72.         }  
  73.     }  
  74.   
  75.     /** 
  76.      * 打印链表 
  77.      *  
  78.      * @param head头指针 
  79.      */  
  80.     public static void printList(ListNode head) {  
  81.         ListNode current = head;  
  82.         while (current != null) {  
  83.             System.out.print(current.getValue() + "、");  
  84.             current = current.getNext();  
  85.         }  
  86.         System.out.println();  
  87.     }  
  88. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序邦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值