降低寻找某数所有因数的时间复杂度

在leetcode中,不乏一些需要寻找某整型数n的所有因数的题目。

若用取余的方法从1到n去遍历查找,时间复杂度是O(n),在面对一些比较大的数字时,会花费非常多的时间。

比如寻找n=100的全部因数,使用以下的代码:

public List<Integer> findFactors(int n){
		List<Integer> factors = new ArrayList<>();
		for(int i=1;i<=n;i++){
			if(n%i == 0){
				factors.add(i);
			}
		}
		return factors;
	}

此时循环体中的内容执行100次。

而从数学的角度来思考,我们可以以sqrt(n)为界限进行分割。

显然,sqrt(n)左侧的每一个因数a,必然存在一个sqrt(n)右侧的一个因数b与之对应,使得b = n/a。这时我们仅仅遍历到1~10,就足以确定100的所有因数:

ab
1100
250
425
520
1010

基于以上思想,可以将代码进行修改:

public static List<Integer> findFactors(int n){
		List<Integer> factors = new ArrayList<>();
		for(int i=1;i*i<=n;i++){
			if(n%i == 0){
				if(i*i == n){
					factors.add(i);//防止添加两个重复的因数
					break;
				}
				factors.add(i);
				factors.add(n/i);
			}
		}
		return factors;
	}

此时循环体中的内容执行10次,时间复杂度降为O(√2)。

在做leetcode第507题完美数时,这一个小小的改变,使得通过全部测试用例所需要的时间从1700ms降低到了2ms,对性能的影响可见一斑。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值