华为笔试2——心中有树笔下有dfs|刷题打卡

181 阅读1分钟

掘金团队号上线,助你 Offer 临门! 点击 查看详情

一、题目描述:

image.png

二、思路分析:

这道题没有15的倍数,不用想太复杂。

我们很难知道arr[i]到底是应该加到哪个数组中,因此可以两种都试试

这个时候对我们来说选择就是一个二叉树

int dfs(){
    return dfs(true)|| dfs(false);
}

即,会有2n2^n种选择(对的,复杂度爆炸)

一般来说能剪枝尽量想办法剪枝,但是没剪枝也没办法的事

三、AC 代码:

#include<iostream>
#include<vector>
using namespace std;
bool isExists(int sum1, int sum2, vector<int> nums, int index){
    if(index == nums.size() && sum1 != sum2) return false;
    if(index == nums.size() && sum1 == sum2) return true;
    if(index < nums.size()) return isExists(sum1+nums[index], sum2, nums, index+1) || isExists(sum1, sum2+nums[index], nums, index+1);
    return false;
}
int main(){
    int n;
    while(cin >> n){
        int tmp;
        int sum1 = 0;
        int sum2 = 0;
        vector<int> sum;
        for(int i = 0; i < n; i++){
            cin >> tmp;
            int tx;
            if(tmp % 3 == 0){
                sum1 += tmp;
            }else if(tmp % 5 == 0){
                sum2 += tmp; 
            }else{
                sum.push_back(tmp);
            }
        } 
        if(isExists(sum1, sum2, sum, 0))
        cout << "true" << endl;
        else
        cout << "false" << endl;
    }
    
}

四、总结:

一般来说,树的遍历,图的遍历,很容易想到dfs,但是遇到有些抽象的选择时,我们要将逻辑转换为一颗树。通过剪枝来解决问题(剪不了也没办法)。