个人随笔
目录
用分治法求x^n次方问题(时间复杂度为O(logn))
2020-02-18 23:05:40

最简单的方法就是一个for循环搞定,和明显我的效率为O(n),那么,这个如果用来做对数器还是不错的,那么我们可不可以提升效率呢,当然可以啦,用分治法的话为O(logn),下面给出算法例子以及普通方法的对数器;

为什么我们的效率是O(lgN)呢?

我们按递归的公式T(n)=aT(n/b)+f(n),由下面的算法可以知道,因为我们只算了一半,所以我们的a=1,b=2,因为相乘是常数时间,所以我们的公式可以变为;

  1. T(n)=T(n/2)+O(1)

很明显,根据master公式,O(n^logb(a))=O(1) 跟O(f(n))是相同的,所以时间复杂度为:O(f(n)logn),也就是O(logn)比O(n)快。

本质上快在只需要算一半即可。

  1. package cn.myforever.test;
  2. public class DivideAndConquer {
  3. /**
  4. * 计算x^n的乘方
  5. * @param x
  6. * @param n
  7. * @return
  8. */
  9. public static int power(int x,int n) {
  10. //分成左右两边
  11. int result = getValue(x,0, n-1);
  12. return result;
  13. }
  14. public static int getValue(int x,int l,int r) {
  15. if(l>=r) {
  16. return x;
  17. }
  18. //这里只需要算一半的即可
  19. if(r%2==1) {
  20. int getLeft = getValue(x,l,(r+l)/2);
  21. return getLeft*getLeft;
  22. }else {
  23. //因为这里多减去了一个,所以这边要多乘上一个x
  24. int getRight = getValue(x,l,(r+l-1)/2);
  25. return getRight*getRight*x;
  26. }
  27. }
  28. /**
  29. * 构造一个对数器,来验证值是否正确
  30. * @param args
  31. */
  32. //2、上面已经有测试方法,下面构造一个绝对正确的方法
  33. public static int getYes(int x,int n) {
  34. int result =1;
  35. for (int i = 0;i < n; i++) {
  36. result=result*x;
  37. }
  38. return result;
  39. }
  40. //构造一个随机数产生器
  41. public static int[] getXN(int xSize,int nSize) {
  42. int x =(int) (Math.random()*(xSize)+1);
  43. int n =(int) (Math.random()*(nSize)+1);
  44. int[] xn = new int[2];
  45. xn[0]=x;
  46. xn[1]=n;
  47. return xn;
  48. }
  49. public static void main(String[] args) {
  50. System.out.println(power(2, 4));
  51. int times =10000;
  52. int xSize =10;
  53. int nSize =10;
  54. boolean flag = true;
  55. for (int i = 0; i < times; i++) {
  56. int[] xn = getXN(xSize,nSize);
  57. int result1 = power(xn[0], xn[1]);
  58. int result2 = getYes(xn[0], xn[1]);
  59. System.out.println("x:"+xn[0]+";n:"+xn[1]+";result1="+result1+";result2="+result2);
  60. if(result1!=result2) {
  61. flag = false;
  62. System.out.println("x:"+xn[0]+";n:"+xn[1]);
  63. break;
  64. }
  65. }
  66. System.out.println(flag?"完全正确":"出错了");
  67. }
  68. }
 1052

啊!这个可能是世界上最丑的留言输入框功能~


当然,也是最丑的留言列表

有疑问发邮件到 : suibibk@qq.com 侵权立删
Copyright : 个人随笔   备案号 : 粤ICP备18099399号-2