21.1.21&22 LeetCode 1414&1640

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;
}```

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值