【リートコード】HOT 100(24)

質問リストの紹介:

LeetCode で最も人気のある 100 の質問を厳選しました。アルゴリズムやデータ構造に慣れていない初心者や、短期間で効率的に上達したい人に適しています。この 100 の質問をマスターすれば、コードで学習する能力がすでに備わっています。世界を通り抜ける能力。

目次

質問リストの紹介:

タイトル: 437. パスサム III - Leetcode

トピックのインターフェース:

問題解決のアイデア:

コード:

終わった、終わった!

タイトル: 416. 等しい和のサブセットの分割 - Leetcode

トピックのインターフェース:

問題解決のアイデア:

コード:

終わった、終わった!

最後に次のように書きます。


タイトル: 437. パスサム III - Leetcode

トピックのインターフェース:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int pathSum(TreeNode* root, int targetSum) {

    }
};

問題解決のアイデア:

この質問では、深さ優先検索を直接使用します。

次に、rootSum 関数を使用してパスの合計を見つけます。

pathSum 自体を繰り返し呼び出して、さまざまなルート ノードのパスの合計を見つけます。

中心となるのは、rootSum が呼び出されるたびに targetSum を減らしてパスの合計を完了することです。

コードは以下のように表示されます:

コード:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    long pathSum(TreeNode* root, long targetSum) {
        if(root == nullptr) return 0;
        long ret = rootSum(root, targetSum);
        ret += pathSum(root->left, targetSum);
        ret += pathSum(root->right, targetSum);
        return ret;
    }
    
private:
    long rootSum(TreeNode* root, long targetSum) {
        if(root == nullptr) return 0;
        long ret = 0;
        if(root->val == targetSum) ret++;
        ret += rootSum(root->left, targetSum - root->val);
        ret += rootSum(root->right, targetSum - root->val);
        return ret;
    }
};

終わった、終わった!

タイトル: 416. 等しい和のサブセットの分割 - Leetcode

トピックのインターフェース:

class Solution {
public:
    bool canPartition(vector<int>& nums) {

    }
};

問題解決のアイデア:

この問題に対する正統な解決策は動的プログラミングであるはずです。

しかし、私は動的プログラミングを知りません。その後、ディスカッションエリアで代替ソリューションを見つけました。

具体的なアイデアは次のとおりです。

なぜなら、それは 2 つの部分集合に分割されており、それらはすべて整数であるため、それらの合計は実際には合計の半分になるからです。

すべての加算と合計の半分を比較すると、それが 2 つの部分集合に分割できるかどうかがわかります。

コードは以下のように表示されます:

コード:

class Solution {
public:
    bool canPartition(vector<int>& nums) {
        int sum = 0;
        for(auto e : nums) sum += e;
        if(sum % 2 != 0) return false;
        int target = sum / 2;
        set<int> st;
        for(int i = 0; i < nums.size(); i++) {
            set<int> snum;
            if(nums[i] == target) return true;
            if(nums[i] < target) snum.insert(nums[i]);
            for(auto num : st) {
                int tarSum = nums[i] + num;
                if(tarSum == target) return true;
                if(tarSum < target) snum.insert(tarSum);
            }
            for(auto k : snum) st.insert(k);
        }
        return false;
    }
};

終わった、終わった!

最後に次のように書きます。

以上が今回の記事の内容となります、読んでいただきありがとうございます。

何かを得たと感じたら、ブロガーに「いいね! 」を与えることができます。

記事の内容に抜けや間違いがある場合は、ブロガーにプライベートメッセージを送信するか、コメントエリアで指摘してください〜

おすすめ

転載: blog.csdn.net/Locky136/article/details/131394528