Skip to content

Conversation

@Ryotaro25
Copy link
Owner

問題へのリンク
https://leetcode.com/problems/split-bst/description/

問題文(プレミアムの場合)
Given the root of a binary search tree (BST) and an integer target, split the tree into two subtrees where the first subtree has nodes that are all smaller or equal to the target value, while the second subtree has all nodes that are greater than the target value. It is not necessarily the case that the tree contains a node with the value target.

Additionally, most of the structure of the original tree should remain. Formally, for any child c with parent p in the original tree, if they are both in the same subtree after the split, then node c should still have the parent p.

Return an array of the two roots of the two subtrees in order.

Example 1:
Input: root = [4,2,6,1,3,5,7], target = 2
Output: [[2,1],[4,3,6,null,null,5,7]]

Example 2:
Input: root = [1], target = 1
Output: [[1],[]]

Constraints:

The number of nodes in the tree is in the range [1, 50].
0 <= Node.val, target <= 1000

備考

次に解く問題の予告
Longest Substring Without Repeating Characters

フォルダ構成
LeetCodeの問題ごとにフォルダを作成します。
フォルダ内は、step1.cpp、step2.cpp、step3.cpp、recursive.cppとmemo.mdとなります。

memo.md内に各ステップで感じたことを追記します。

**3回書き直しやりましょう、といっているのは、不自然なところや負荷の高いところは覚えられないからです。**

## 他の方の解法
gotoさんは再帰の解法を用いている。
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

再帰とループの中間を念頭において、対応関係から相互に変換できるようにしておくといいでしょう。
一例として、中間に来るものは、このような感じです。

void splitBSTHelper(TreeNode* node, int target, TreeNode** left, TreeNode** right) {
  if (!node) {
    // *left = nullptr;
    // *right = nullptr;
    return;
  }
  if (node->val > target) {
    *left = node;
    node = node->left;
    (*left)->left = nullptr;
    splitBSTHelper(node, target, &(*left)->left, right);
  } else {
    *right = node;
    node = node->right;
    (*right)->right = nullptr;
    splitBSTHelper(node, target, left, &(*right)->right);
  }
}

vector<TreeNode*> splitBST(TreeNode* node, int target) {
  TreeNode* left;
  TreeNode* right;
  splitBSTHelper(node, target, &left, &right);
  return {left, right};
}

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@oda

レビューありがとうございます。またコードもありがとうございます。
こちらを元に自分でも中間のバージョンで実装してみました。

対応関係から相互に変換できるようにしておくといいでしょう。

変換する作業の中でより処理が理解出来たような気がします。

一点質問ですが、TreeNode** leftや&(*left)->leftを用いる意図などあるのでしょうか?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

選択肢は色々です。
Google のスタイルが書き込み先はポインターというものだったのでそれに従っています。

あれ、このコード左右逆になっていますか。

Copy link
Owner Author

@Ryotaro25 Ryotaro25 Jan 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@oda
この辺りですかね。
https://google.github.io/styleguide/cppguide.html#Inputs_and_Outputs

Non-optional input parameters should usually be values or const references, while non-optional output and input/output parameters should usually be references (which cannot be null).

Google guideも何度か見返すようにします🙇‍♂️

あれ、このコード左右逆になっていますか。

このまま実行したところ左右が逆となっておりました。

node->val > targetがtrueの場合、*left = node;としておりますが
targetが現在のnodeより小さいので、
今いるNodeがleftに紐づくのではなくrightに紐づく必要があるのかと思いました。

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

昔はアウトプットはポインターでしたが、2020年のこのあたりで変更されていますね。
google/styleguide@7a7a2f5#diff-bcadcf8be931ffdd5d6a65c60c266039cf1f96b7f35bfb772662db811214c5a0L1710

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@oda
1708行目あたりですねありがとうございます🙇‍♂️

vector<TreeNode*> splitBST(TreeNode* root, int target) {
TreeNode* node = root;

TreeNode* smaller_head = new TreeNode();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

head はリンクリストの先頭のノードを表す単語だと思います。 smaller_root はいかがでしょうか?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nodchip
いつもレビューありがとうございます。
同じものだとごっちゃになっておりました。step4にて修正しました。


while (node) {
if (node->val > target) {
// 現在のnodeの値の方が小さいのでnodeを左側に紐づける

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

コメント逆ですかね?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Yoshiki-Iwasa
レビューありがとうございます。

コメントが良くなかったです🙇‍♂️
左側は左側なのですが正しくは、
「現在のnodeの値の方が小さいので、largerの左側に現在のnodeを紐づける」でした🙇‍♂️
こちらで伝わりますでしょうか。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants