1417. Reformat The String 链接到标题 重新格式化字符串,使得字母与数字交叉连接,先分别找出字母与数据,使用 zip_longest 来生成交叉后的元组,然后拼接得到目标字符串。
class Solution: def reformat(self, s: str) -> str: a=re.findall(r'\d',s) b=re.findall(r'[a-z]',s) if abs(len(a)-len(b))>1: return '' a,b=sorted([a,b],key=len) return ''.join(map(''.join,itertools.zip_longest(b,a,fillvalue=''))) 1414. Find the Minimum Number of Fibonacci Numbers Whose Sum Is K 链接到标题 参考:https://leetcode-cn.com/problems/find-the-minimum-number-of-fibonacci-numbers-whose-sum-is-k/solution/tan-xin-jian-dan-zheng-ming-by-wyjoutstanding/
判定性:保证K一定能由斐波那契数组成,数据归纳法可证明
最小性:什么样的组合能最短?
相邻合并:2个相邻的数可合并为二者的和,长度-1,因为f(n)=f(n-1)+f(n-2)。满足该条件的组合必定是间隔出现,但是又可能重现重复的值,这对于编程很不利。 重值转换:两个相同的值一定可以转换为两个不同的值,因为f(n)+f(n)=f(n)+f(n-1)+f(n-2)=f(n+1)+f(n-2),一个比f(n)大,一个更小,这是等价转换,不会减小组合长度,但是会带来一个很好的性质,即单调递增性质。 因此,重复使用以上两个操作后的组合数列,必定是一个无相邻值的递增数列,由于数列均为正数且和为K,因此值越大个数自然越小。
问:
那会不会出现一种情况呢,就是如果减去最大的斐波那契数的话,剩下的数只能拆分成两个斐波那契数,而如果减去第二大的斐波那契数或者更小的斐波那契数的话,剩下的数刚好是斐波那契数?
答:
可用反证法,假设总和为k,且f(m-1)<k<f(m)
那么对应你的第一种情况是k=f(m-1)+f(i)+f(j),1<=f(i),f(j)<=f(m-2);
对应你的第二种情况是k=f(m-2)+f(l),其中,1<=f(l)<=f(m-3)。
假设你说的情况成立,那么以上两个等式必定相等,即f(m-1)+f(i)+f(j)=f(m-2)+f(l),
因为f(m-1) = f(m-2) + f(m-3), f(l)<=f(m-3),而f(i)和f(j)均不可能为0,因此等式不可能成立。
(左侧恒大于右侧,只有消去f(i)和f(j)才有可能取等)
当第二个等式的f(m-2)取更小值时更不可能成立。因此,推翻假设。
class Solution: def findMinFibonacciNumbers(self, k: int) -> int: ls=self.fib(k) res=0 while k: if k>=ls[-1]: k-=ls[-1] res+=1 else: ls.