zoukankan      html  css  js  c++  java
  • 算法题3 寻找丑数&数值逼近

    题目

    只包含因子2、3、5的数字被称为丑数。例如4和6是丑数,而14不是丑数,因为含有因子7。习惯上把1作为第一个丑数。求按从小到大顺序的第1500个丑数。

    分析

    假设一个丑数顺序数组ugly_nums[],对于其中一个丑数ugly=ugly_nums[x],存在2*ugly_nums[i-1]<=ugly,2*ugly_nums[i]>ugly,也就是说2乘以一个丑数刚刚大于丑数ugly;

    同理也存在3*ugly_nums[j-1]<=ugly,3*ugly_nums[j]>ugly,和5*ugly_nums[k-1]<=ugly,5*ugly_nums[k]>ugly。

    那么第x+1个丑数应该是3个倍数结果中最小的那个,即ugly_nums[x+1]=min{2*ugly_nums[i],3*ugly_nums[j],5*ugly_nums[k]};

    这应该算是一种数值逼近的思想,遇到一些需要计算的数值需找时可以考虑,比如找顺序数组中满足和为某值得数字对

    算法需要借助一个辅助数组存储丑数,空间复杂度O(n)。时间复杂度O(n)

    代码

     1 int FindUglyNum(unsigned int index)
     2 {
     3     int *uglynums=new int[index];
     4 
     5     uglynums[0]=1;
     6     uglynums[1]=2;
     7     uglynums[2]=3;
     8     uglynums[3]=4;
     9     uglynums[4]=5;
    10 
    11     unsigned int i=1,j=1,k=1;
    12     unsigned int min_uglynum=0;
    13     unsigned int idx=4;
    14     while (idx<index)
    15     {
    16         if (2*uglynums[i]<uglynums[idx])
    17         {
    18             i++;
    19         }
    20         if (3*uglynums[j]<uglynums[idx])
    21         {
    22             j++;
    23         }
    24         if (5*uglynums[k]<uglynums[idx])
    25         {
    26             k++;
    27         }
    28         min_uglynum=MIN(MIN(2*uglynums[i],3*uglynums[j]),5*uglynums[k]);
    29         uglynums[++idx]=min_uglynum;
    30     }
    31 
    32     return uglynums[index-1];
    33 }

     

    数值逼近之和为n的连续整数序列

      输入一个整数,输出所有和为n的连续正数序列。例如:输入15,由于15=7+8=4+5+6=1+2+3+4+5,所以输出的序列为1,2,3,4,5;4,5,6;7,8

    分析

      由于要求的子序列是连续的,那么就可以连续数字的相加一点一点逼近n。设small=big=1,sum=small+big,移动big并计算新sum=sum+big,直到sum>=n,如果sum=n,则small到big是所求的子序列之一,

      若sum>n,则调整small向后移动,直到sum<=n。循环依次调整big和small,直到small=n/2

    代码

     1  void FindContinuousNumbers(int n)
     2  {
     3      int small = 1,big = 1;
     4      int middle = n/2;
     5      int sum = small;
     6 
     7      while(small <=middle&&big<=n)
     8      {
     9          sum += big;
    10 
    11          if(sum == n)
    12          {
    13              for(int i = small;i <= big;++i)
    14                  cout<<i<<" ";
    15              cout<<endl;
    16          }
    17  
    18          while(sum > n)
    19          {
    20              sum-=small;
    21              small++;
    22  
    23              if(sum == n)
    24              {
    25                  for(int i = small;i <= big;++i)
    26                      cout<<i<<" ";        
    27                  cout<<endl;
    28              }
    29              
    30          }
    31          big++;
    32      }
    33  }

    数值逼近之升序数组中和为n的数字对

      输入一个已经按升序排列的数组,一个给定的数字num,在数组中查找两个数,使得它们的和等于n。要求时间复杂度为O(n),如果存在多对满足条件的数字对,只给出一对即可

    分析:

      既然是已经排列好的数组,又是求和,那么也可以用数值逼近的方式求解。设small=arr[0],big=arr[n-1],sum=small+big,若sum=num,则small和big就是要找的数对之一,若sum>num,则向前调整big,若sum<num,则向后调整small,直至small=big,循环结束。本题既然只要求给出一对数字,那么当sum=num时就可以停止查找了

    代码 

     1  void FindSumPairs(int arr[],int len,int num)
     2  {
     3      if (arr==NULL||len<=0)
     4          throw std::exception("Invalid input.");
     5      int small=0,big=len-1;
     6      int sum=0;
     7 
     8      while (small<big)
     9      {
    10          sum=arr[small]+arr[big];
    11 
    12          if (sum==num)
    13              cout<<arr[small]<<' '<<arr[big]<<endl;
    14 
    15          if (sum>num)
    16              big--;
    17 
    18          if (sum<num)
    19              small++;
    20      }
    21 
    22  }

        

  • 相关阅读:
    pytorch nn.Parameters vs nn.Module.register_parameter
    pytorch COCO2017 目标检测 (一)DataLoader
    focal loss 两点理解
    pytorch 目标检测 图像预处理
    C++ 使用copy_if获得数组vector掩膜
    pytorch 网络可视化
    SHELL学习笔记二
    SHELL学习笔记一
    Linux命令笔记一
    VLOOKUP返回#N/A结果
  • 原文地址:https://www.cnblogs.com/wangzaizhen/p/5167015.html
Copyright © 2011-2022 走看看