【LeetCode 279】完全平方数

15 篇文章 0 订阅
/*
难度:中等
给定正整数n,找到若干完全平方数,使得它们的和等于n,并且完全平方数的个数最少。

示例:
输入 n=12
输出 3
12 = 4 + 4 + 4

输入 n=13
输出 2
13 = 4 + 9

假定:1 <= n <= 10000
*/ 
extension Daily {
	static func test_leetcode279() {
		let n = 4308
		let start = Date()
		print(start)
		let res = Daily.leetcode279(n)
		print(Date().timeIntervalSince(start))
		print("最终结果 \(res)")
	}
	static func leetcode279(_ n: Int) -> Int {
		if n < 1 || n > 10000 {
			print("n is invalid")
			return 0
		}
		var max = Int(sqrt(Double(n)));
		if max * max == n {
			print("n 是完全平方数, \(max)")
			return 1
		}
		let squares = [0,1,4,9,16,25,36,49,64,81,100,121,144,169,196,225,256,289,324,361,400,441,484,
					   529,576,625,676,729,784,841,900,961,1024,1089,1156,1225,1296,1369,1444,1521,
					   1600,1681,1764,1849,1936,2025,2116,2209,2304,2401,2500,2601,2704,2809,2916,
					   3025,3136,3249,3364,3481,3600,3721,3844,3969,4096,4225,4356,4489,4624,4761,
					   4900,5041,5184,5329,5476,5625,5776,5929,6084,6241,6400,6561,6724,6889,7056,
					   7225,7396,7569,7744,7921,8100,8281,8464,8649,8836,9025,9216,9409,9604,9801,10000]
		max += 1
		let cols = max*max + 1
		var line = Array(repeating: 0, count: cols ); 
		
		for idx in 1..<line.count {
			line[idx] = idx
		}
		for idx in 1...max {
			line[squares[idx]] = 1;
			if idx < max {
				line[squares[idx]+1] = 2;
			}
		}
		aloop: for idx in 2...max {
			let pre = squares[idx-1]
			
			var times = 1
			var xxx = pre
			for j in stride(from: pre, through: n, by: pre) {
				for sidx in 0..<pre {
					let ridx = j + sidx
					if ridx > n {
						break
					}
					if line[ridx] == 1 || line[ridx] == 2 {
						continue
					}
					let tran = line[ridx - xxx]  + times
					if tran < line[ridx] {
						line[ridx] = tran
					}
				}
				times += 1
				xxx += pre
				if idx == max && j == n {
					break aloop
				}
			}
		}
		return line[n]
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值