selfnumbers查找的实现与分析

本文探讨了Self Numbers的定义及高效求解方法,通过引入二分查找算法优化了初始O(n^3)的时间复杂度至O(nlogn),同时减少了空间需求。

今天有一个高中的同学在网上问了我一到ACM的题,是关于找selfnumbers数的,要求运行时间至少要是Onlogn)),空间要比On)要小。

立马我就上wikipedia网查一下,关于selfnumbers的定义和有关数学的解法(没办法啊,咱数学功底还没那么厚,只能站在巨人的肩膀上,^_^)O(_)O哈哈~wikipedia还真伟大啊,还真有。我摘抄了一部分:(http://en.wikipedia.org/wiki/Self_number

Reduction tests

Luke Pebody showed (Oct 2006) that a link can be made between the self property of a large number n and a low-order portion of that number, adjusted for digit sums:

a) In general, n is self if and only if m = R(n)+SOD(R(n))-SOD(n) is self

Where:

R(n) is the smallest rightmost digits of n, greater than 9.d(n)

d(n) is the number of digits in n

SOD(x) is the sum of digits of x, the function S10(x) from above.

b) If n = a.10^b+cc<10^b, then n is self if and only if both {m1 & m2} are negative or self

Where:

m1 = c - SOD(a)

m2 = SOD(a-1)+9.b-(c+1)

c) For the simple case of a=1 & c=0 in the previous model (i.e. n=10^b), then n is self if and only if (9.b-1) is self

SOD(n) is the sum of all digits in n

d(n) is the number of digits in n

哈哈,看到了没,b方案就是我们要找的数学解决方案。下面是我刚开始写的解决方案:

看一下Solve函数里的双层循环,就知道它的运行时间是O(n^3),差太多了。函数的运行时间都耗在这里了。看来不行啊。行,把他修改一下,知道两个循环都是为了求r中是否有m1,m2的存在,没必要要花费双层循环来解决这个问题啊。行,要找m1和m2吗。R中数字是排序号的,那可以用二分查找啊。下面是我的简单实现:

来测试一下,(图1是第一的实现(查找10000以内的selfnumbers),图2是第二次的实现(查找1000000以内的self))。

图一

 

图二

 

看到了差距了吧。来分析一下他的时间,这里主要就时间就花在二分查找里,他的时间是O(nlog(n));而空间是O(n),经过我测试空间可以是n/10.(n要比较大)。

行了。就写到这里了,如果朋友您有更好的解决方案,欢迎来找我讨论。我将非常高兴。

程序设计分析是计算机科学领域的重要组成部分,涵盖了从程序的设计到对其性能等方面进行评估的多个环节。 ### 程序设计 - **基本概念**:程序设计是指设计、编制、调试程序的方法和过程,以实现特定的功能或解决特定的问题。它是目标明确的智力活动,要求设计者具备良好的逻辑思维和问题解决能力。 - **设计方法** - **结构化程序设计**:采用自顶向下、逐步求精及模块化的程序设计方法,将一个复杂的问题分解为若干个相对简单的子问题,每个子问题对应一个模块,各模块之间通过特定的接口进行交互。例如在编写一个学生成绩管理系统时,可以将系统分解为学生信息录入模块、成绩计算模块、成绩查询模块等。 ```python # 简单的结构化程序示例:计算两个数的和 def add_numbers(a, b): return a + b result = add_numbers(3, 5) print(result) ``` - **面向对象程序设计**:将数据和操作数据的方法封装在一起,形成对象。对象之间通过消息传递进行交互,具有封装性、继承性和多态性等特点。以一个图形绘制系统为例,可定义一个基类“图形”,然后派生出“圆形”“矩形”等子类,每个子类可以有自己独特的属性和方法。 ```python # 面向对象程序示例:定义一个简单的类 class Animal: def __init__(self, name): self.name = name def speak(self): pass class Dog(Animal): def speak(self): return f"{self.name} says Woof!" dog = Dog("Buddy") print(dog.speak()) ``` - **编程语言**:不同的编程语言适用于不同的应用场景。例如,Python 因其简洁易读、拥有丰富的库,常用于数据科学、人工智能等领域;Java 具有跨平台性,广泛应用于企业级应用开发;C++ 性能高,常用于系统软件、游戏开发等。 ### 程序分析 - **复杂度分析** - **时间复杂度**:衡量程序运行时间随输入规模增长的变化趋势。常见的时间复杂度有常数时间 $O(1)$、对数时间 $O(log n)$、线性时间 $O(n)$、平方时间 $O(n^2)$ 等。例如,在一个长度为 $n$ 的数组中查找一个元素,使用顺序查找的时间复杂度为 $O(n)$,而使用二分查找(前提是数组有序)的时间复杂度为 $O(log n)$。 ```python # 线性查找示例 def linear_search(arr, target): for i in range(len(arr)): if arr[i] == target: return i return -1 arr = [1, 2, 3, 4, 5] target = 3 print(linear_search(arr, target)) ``` - **空间复杂度**:分析程序运行过程中所占用的额外存储空间随输入规模的变化情况。例如,在递归调用中,递归栈的深度会影响空间复杂度。 - **正确性证明**:确保程序在所有可能的输入下都能产生正确的输出。可以采用数学归纳法、演绎推理等方法进行证明。例如,对于一个计算 $n$ 的阶乘的程序,可以通过数学归纳法证明其正确性。 ```python # 计算阶乘并证明正确性 def factorial(n): if n == 0 or n == 1: return 1 else: return n * factorial(n - 1) print(factorial(5)) ``` - **性能优化**:通过分析程序的瓶颈,采取相应的优化策略。例如,使用更高效的算法、减少不必要的计算、优化数据结构等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值