35. Search Insert Position(C++)


今回は説明文に「昇順にソート済みの配列が与えられる」旨の記載があるので、2分探索を使用します。
(O(log n)のアルゴリズムを使ってねとも書いてあります。)

再帰を使用する方法

class Solution {
public:
    int searchInsert(const vector<int>& nums, int target) {
        if (nums.size() <= 1) {
            return nums.empty() || target <= nums.front() ? 0 : 1;
        }

        const size_t mid = nums.size() / 2;
        if (nums[mid] == target) {
            return mid;
        }
        return target < nums[mid]
                ? searchInsert(std::vector<int>(nums.cbegin(), nums.cbegin() + mid), target)
                : mid+1 + searchInsert(std::vector<int>(nums.cbegin() + mid+1, nums.cend()), target);
    }
};

真ん中の要素がtargetと一致するか、見ている配列の要素数が1以下になるまで比較し続けます。

再帰呼び出しする際に std::vector右辺値を渡しているため、引数の定義には const 修飾が必要になります。

時間計算量、空間計算量は、共に O(log n) です。

繰り返し構文を使用する方法

class Solution {
public:
    int searchInsert(const vector<int>& nums, int target) {
        int begin = 0;
        int end = nums.size() - 1;
        while (begin <= end) {
            int mid = (begin + end) / 2;
            if (nums[mid] == target) {
                return mid;
            }
            if (target < nums[mid]) {
                end = mid - 1;
            } else {
                begin = mid + 1;
            }
        }
        return begin;
    }
};

時間計算量は O(log n) 、空間計算量は O(1) です。

再帰処理はスタックを消費するので、メモリ的にはこちらの方が効率は良いはずです。
(LeetCode上では誤差程度しか変わりませんでしたが……)

以上です!


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です