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

質問リストの紹介:

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

目次

質問リストの紹介:

トピック: 34. ソートされた配列内の要素の最初と最後の位置を見つける - Leetcode

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

問題解決のアイデア:

コード:

終わった、終わった!

タイトル: 39. 組み合わせの合計 - Leetcode

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

問題解決のアイデア:

コード:

終わった、終わった!

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


トピック: 34. ソートされた配列内の要素の最初と最後の位置を見つける - Leetcode

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

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {

    }
};

問題解決のアイデア:

この質問は質問を見て、時間計算量の要件を確認します。

暴力は通らない、ということはすぐにわかるでしょう。2つのポイントを押さえなければなりません。

一般的な考え方は、二分探索を使用して左右の境界を見つけることです。

具体的な考え方は以下のとおりです。

二分探索で質問に必要なターゲットの位置を見つけます (nums[mid] == target)

それから 2 つのケースがあります。

左側の境界を探している場合は、常に過去に近い右側の境界を更新します。

右の境界を探している場合は、左の境界を更新し続けて通過してください。

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

コード:

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        return {search_range(nums, target, "left"), search_range(nums, target, "right")};
    }
private:
    int search_range(const vector<int>& nums, int target, const string& side) {
        int left = 0, right = nums.size() - 1;
        int res = -1;
        while(left <= right) {
            int mid = (left + right) >> 1;
            if(nums[mid] < target) { //经典二分
                left = mid + 1;
            }
            else if(nums[mid] > target) {
                right = mid - 1;
            }
            else { //nums[mid] == target
                res = mid;
                if(side == "left") { //更新右边界靠过去
                    right = mid - 1;
                }
                if(side == "right") { //更新左边界靠过去
                    left = mid + 1;
                }
            }
        }
        return res;
    }
};

終わった、終わった!

タイトル: 39. 組み合わせ和 - Leetcode

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

class Solution {
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {

    }
};

問題解決のアイデア:

彼は、この質問の組み合わせの数は 150 を超えないと言い、この質問は暴力で勝つことはできないとすぐに思いました。

直接的な暴力にはいくつかの問題があるようで、同じ数字が複数選択される可能性があり、ループではこれを実現するのは簡単ではありません。

この時考えて検索してみましたが、この質問はdfsが勝つのは大した問題ではありません。

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

コード:

class Solution {
public:
    vector<int> v; //每个合格的数组(sum == target)
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<vector<int>> res; //存返回的数组
        dfs(candidates, res, target, 0, 0); //搜索
        return res;
    }
private:
    void dfs(const vector<int>& candidates, vector<vector<int>>& res,
            int target, int sum, int begin) {
        if(sum == target) { //符合条件
            res.push_back(v);
            return;
        }
        if(sum > target) return; //剪枝
        for(int i = begin; i < candidates.size(); i++) { //搜索
            v.push_back(candidates[i]);
            dfs(candidates, res, target, sum + candidates[i], i);
            v.pop_back(); //回溯
        }
    }
};

終わった、終わった!

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

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

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

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

おすすめ

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