LeetCode 1414 Find the Minimum Number of Fibonacci Numbers Whose Sum Is K
问题描述:
//谷歌翻译来的,别骂www
给定整数k,返回总和等于k的最小斐波纳契数。 相同的斐波那契数可以多次使用。
斐波那契数定义为:
F1 = 1
F2 = 1
Fn = Fn-1 + Fn-2,其中n> 2。
对于给定的约束,可以保证总能找到总和为k的斐波那契数。
没写几个LeetCode的题目(三道),这一题应该是写过最简单的。(但是或许方法比较笨)
思路
题目对k的约束是到1 <= k <= 10^9
所以找到10^10的斐波那契数应该是第45左右
考虑了一下,吧一个数拆成其他数字之和,不应该乱拆,按照顺序的话有从大到小,或者从小到大
如果是从小到大显然是很难找的(总不能找一堆1)
从大到小的找就应该先找比k小的数字中最大的数字设为a;
那现在从k的组成中有一个a,斐波那契数的个数设为num则要加1;
下一步想了想应 k=k-a;
于是就可以一步一步找下去,把k缩小这样有利于寻找和循环的解决
当k为斐波那契数时循环终止
代码片段
#include <stdio.h>
#pragma warning (disable:4996)
int findMinFibonacciNumbers(int k)
{
int F[50];
int num=0;
F[0] = 1;
F[1] = 1;
for (int i = 2; i < 45; i++)//存储斐波那契数
F[i] = F[i - 1] + F[i - 2];
for (;;)
{
for (int j = 0; j < 44; j++)
{
if (k == F[j])//k为斐波那契数时退出
{
num++;
return num;
}
if (k > F[j] && k < F[j + 1])//寻找<k的最大斐波那契数
{
k = k - F[j];//将k的部分去除进行下一次寻找
num++;
break;
}
}
}
}
int main()
{
int F[50];
int num = 0;
F[0] = 1;
F[1] = 1;
for (int i = 2; i < 45; i++)
{
F[i] = F[i - 1] + F[i - 2];
printf("%d\n", F[i]);
}
return 0;
}
Check Array Formation Through Concatenation
问题描述:
您将得到一个由不同整数组成arr的数组和一个由整数数组组成的数组pieces,
其中的整数pieces是不同的。您的目标是arr通过pieces 以任意顺序串联数组来形成。但是,你是不是允许重新排序整数每个阵列中pieces[i]。
true 如果有可能从返回数组arr,则返回pieces。否则,返回false。
思路1(自己想的):
1.整数各不相同
2.pieces中的数组的数字顺序不能变化
3.首先考虑在数组arr中寻找pieces中的数组的首元
4.找到pieces[i]的首元之后,在以piecs[i]的长度作为标准,往后比对
5.判断:比对时是否超出arr的大小,是否出现不匹配(即顺序乱了)
代码片段:
#include <stdio.h>
bool canFormArray(int* arr, int arrSize, int** pieces, int piecesSize, int* piecesColSize)
{
int num = 0;
int flag = 0;//计数变量
for (int i = 0; i < piecesSize; i++)
{
flag = 0;
for (num = 0; num < arrSize; num++)//这里采用的是遍历arr、的方法并与pieces中的数组首元比较
//和上面思路不太一样,但是道理相通
{
if (arr[num] == pieces[i][0])//匹配到pieces
{
for (int j = 0; j < piecesColSize[i]; j++, num++)//开始向后匹配
{
if (num > arrSize - 1 || arr[num] != pieces[i][j])//不和情况,返回false
return false;
}
}
else if (arr[num] != pieces[i][0])//匹配
flag++;
}
if (flag == arrSize)//一直没有匹配到首元,返回false
return false;
}
return true;//没有发生返回false
}
int main()
{
int arr[4] = { 1,3,5,7 };
int pieces[1][4] = { {2,4,6,8} };
int piecesSize[1] = { 1 };
int piecesColSize[1] = { 4 };
int* p = pieces[0];
int j = canFormArray(arr, 4, &p, 1, piecesColSize);
printf("%d", j);
return 0;
}
#思路2(看了别人的hash):
1.因为数字并不相同,可以将arr[i]映射到hash中
2.通过变化hash[arr[i]]=i+1 使得在连续这一关系更为容易表达
代码:
#include <stdio.h>
bool canFormArray(int* arr, int arrSize, int** pieces, int piecesSize, int* piecesColSize)
{
int hash[101] = { 0 };
for (int i = 0; i < arrSize; i++)//映射
{
hash[arr[i]] = i + 1;
}
for (int i = 0; i < piecesSize; i++)//
{
if (hash[pieces[i][0]] == 0)//arrr中无与之匹配(初始值为0,映射后为i+1)
return false;
else
{
for (int j = 0; j < piecesColSize[i] - 1; j++)
{
if (hash[pieces[i][j]] != hash[pieces[i][j + 1]] - 1)//pieces[i]中相邻两项在arr中不连续
return false;
}
}
}
return true;
}
int main()
{
int arr[4] = {1,2,3,4 };
int pieces[3][3] = { {4},{1,2},{3} };
int piecesColSize[3] = {1,2,1 };
int* p = pieces[0];
int j = canFormArray(arr, 4,&p,3, piecesColSize);
printf("%d", j);
return 0;
}```