【leetcode每日一题】面试题 16.11. 跳水板

【题目:】面试题 16.11. 跳水板

你正在使用一堆木板建造跳水板。有两种类型的木板,其中长度较短的木板长度为shorter,长度较长的木板长度为longer。你必须正好使用k块木板。编写一个方法,生成跳水板所有可能的长度。
返回的长度需要从小到大排列。
示例:
输入:
shorter = 1
longer = 2
k = 3
输出: {3,4,5,6}
提示:
0 < shorter <= longer
0 <= k <= 100000

【感受:】题很简单,但思维方式的不同决定了水平的高低,看了解析才发现我以为做对了就是真的懂了,其实是瞎猫碰见死耗子。

先分享下我的弱鸡思路:k块板子是固定的,短的用了i块,长的就是k-i,一个k+1次循环,再去除重复长度(其实这个长度除了一种情况外就不会重复)就KO了。

#include <set>

class Solution {

public:

    vector<int> divingBoard(int shorter, int longer, int k) {

        vector<int> result;

        if (k <= 0)

        {

            return result;

        }

        set<int> tmp;

        for (int i = 0; i <= k; ++i) 

        {

            int length = i * shorter + (k - i) * longer;

            tmp.insert(length);

        }

        result.assign(tmp.begin(),tmp.end());

        return result;

    }

};

虽然通过了,但看了解析才发现自己的思考是多么不严谨。

官方解析:(有理有节还有公式推导)

首先考虑两种边界情况。
1.如果 k=0k=0k=0,则不能建造任何跳水板,因此返回空数组。
2.如果 shortershortershorter 和 longerlongerlonger 相等,则建造的跳水板的长度是唯一的,都等于 shorter∗kshorter*kshorter∗k,因此返回长度为 111 的数组,数组中的元素为 shorter∗kshorter*kshorter∗k。
3.然后考虑一般情况,即 shorter<longershorter<longershorter<longer 且 k>0k>0k>0。由于短木板和长木板一共使用 kkk 块,因此一共有 k+1k+1k+1 种组合,每种组合下建造的跳水板长度都是不一样的,一共有 k+1k+1k+1 种不同的长度。
为什么每种组合下建造的跳水板长度都是不一样的?考虑以下两种不同的组合:第一种组合,有 iii 块长木板,则跳水板的长度是 shorter∗(k−i)+longer∗ishorter*(k-i)+longer*ishorter∗(k−i)+longer∗i;第二种组合,有 jjj 块长木板,则跳水板的长度是 shorter∗(k−j)+longer∗jshorter*(k-j)+longer*jshorter∗(k−j)+longer∗j。其中 0≤i<j≤k0 \leq i<j \leq k0≤i<j≤k。则两种不同的组合下的跳水板长度之差为:
(shorter∗(k−i)+longer∗i)−(shorter∗(k−j)+longer∗j)=(longer−shorter)∗(i−j)(shorter*(k-i)+longer*i)-(shorter*(k-j)+longer*j)=(longer-shorter)*(i-j)
(shorter∗(k−i)+longer∗i)−(shorter∗(k−j)+longer∗j)=(longer−shorter)∗(i−j)
由于 longer>shorterlonger>shorterlonger>shorter 且 i<ji<ji<j,因此上式的值小于 000。由此可见,任意两种不同的组合下的跳水板长度都是不一样的,而且使用的长木板越多,跳水板的长度越大。
因此创建长度为 k+1k+1k+1 的数组 lengths\text{lengths}lengths,对于 0≤i≤k0 \leq i \leq k0≤i≤k,令 lengths[i]=shorter∗(k−i)+longer∗i\text{lengths}[i]=shorter*(k-i)+longer*ilengths[i]=shorter∗(k−i)+longer∗i,则 lengths\text{lengths}lengths 包含跳水板所有可能的长度,且长度为升序排序。

class Solution {

public:

    vector<int> divingBoard(int shorter, int longer, int k) {

        if (k == 0)

        {

            return vector<int> ();

        }

        if (shorter == longer)

        {

            return vector<int> (1,k*shorter);

        }

        vector<int> lengths(k + 1);

        for (int i = 0; i <=k; ++i)

        {

            lengths[i] = shorter * (k - i) + longer * i;

        }

        return lengths;

    }

};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值