一.问题描述
Given an integer n
. No-Zero integer is a positive integer which doesn't contain any 0 in its decimal representation.
Return a list of two integers [A, B]
where:
A
andB
are No-Zero integers.A + B = n
It's guarateed that there is at least one valid solution. If there are many valid solutions you can return any of them.
Example 1:
Input: n = 2 Output: [1,1] Explanation: A = 1, B = 1. A + B = n and both A and B don't contain any 0 in their decimal representation.
Example 2:
Input: n = 11 Output: [2,9]
Example 3:
Input: n = 10000 Output: [1,9999]
Example 4:
Input: n = 69 Output: [1,68]
Example 5:
Input: n = 1010 Output: [11,999]
Constraints:
2 <= n <= 10^4
二.解题思路
方法一:暴力搜索
从1~n,每个num1和num2的组合都试试,总能成功不是。
时间复杂度:O(NK),K是n的位数长度。
方法二:拆分法
对n来说,从每一位开始拆分,比如108,个位把8拆分,1给num1,7给num2.
主要处理位数值为1或者0的时候,把前一位考虑进来。
为1,num1分2,num2分剩下的。
为0,num1分1,num2分剩下的。
当然怎么分有多种选择,只要不要让两边有0的情况就好了。
时间复杂度O(K).
方法三:方法一的优化
方法一我们试了所有的组合,其实浪费了很多时间在无效的组合上。
比如说num1=1,num2=1099,
迭代到num1=101,num2=999,才是第一个有效的组合。
所以,为什么不直接变化到有效的组合上了?
具体来说:
我们每次检测num1和num2中是否含有0,对于含有0的数,如果是num1,我们加上一个最小的数(这个数不会改变这个数的其他位)来删掉这个0。对于num2,我们减去一个最小的数来删掉这个0。
比如说1099,减去100来删掉这个0,变成999.
为什么是一加一减,因为要避免比如说,前一个迭代num2有0,减掉一个数,num2没0了,这个数加到num1,上,num1变成有0的状态了,然后num1没0了,这个数加到num2上它又变成有0状态,就这样死循环了。
详细可以看代码。
时间复杂度:O(K*K).
ps:看起来方法三比方法二时间复杂度高,但是其实一个数中有0的情况还是比较少的,因此如果数据集分布均匀的话,方法三会快很多。
这个方法我第一次提交超过100%,之后只有超过90%,搞不大明白。
更多leetcode算法题解法: 专栏 leetcode算法从零到结束 或者 leetcode 解题目录 Python3 一步一步持续更新~
三.源码
方法一:
# version 1
# from https://leetcode.com/problems/convert-integer-to-the-sum-of-two-no-zero-integers/discuss/485620/Python
a = 1
b = n -1
for i in range(n):
if '0' not in list(str(a + i)) and '0' not in list(str(b-i)):
return [a+i,b-i]
#version 2:
#from leetcode example
class Solution:
def getNoZeroIntegers1(self, n):
a = 1
while '0' in f'{a}{n-a}':
a += 1
return [a, n-a]
class Solution:
def getNoZeroIntegers(self, n: int) -> List[int]:
a, b = 0, 0
rest = n % 10
power = 1
while n > 1:
n = n // 10
if rest > 1:
a += 1*power
b += (rest - 1)*power
else:
a += (rest+1)*power
b += 9*power
n -= 1
rest = n % 10
power *= 10
if n == 1:
a += power
return [a, b]
方法三:我自己写的
class Solution:
def getNoZeroIntegers(self, n: int) -> List[int]:
def isContainZero(num):
i=1
while num!=0:
if num%10==0:return i
num//=10
i+=1
return 0
num1,num2,flag1,flag2=1,n-1,1,1
while flag1 or flag2:
flag1=isContainZero(num1)
if flag1:num1+=10**(flag1-1)
num2=n-num1
flag2=isContainZero(num2)
if flag2:num2-=10**(flag2-1)
num1=n-num2
return [num1,n