Skip to content

Conversation

@potrue
Copy link
Owner

@potrue potrue commented Aug 27, 2025

auto it = upper_bound(nums.begin() + i, nums.end(), nums[i-1]);
swap(nums[i-1], *it);
}
};

Choose a reason for hiding this comment

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

添字とイテレータが混ざっているのが気になりました。混ぜて書いても良いものなのでしょうか?

Copy link
Owner Author

@potrue potrue Aug 27, 2025

Choose a reason for hiding this comment

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

upper_boundがindexでなくイテレーターを返すのでこうなってしまいました。(見返してみるとiをイテレーターにすべきだと感じました)
混ぜて書いても良いもの、というのはスタイル的な観点でしょうか。スタイルガイドなどでの直接の言及は見つけられなかったんですが、おっしゃる通り基本的に揃えた方が見やすいと思います。

Choose a reason for hiding this comment

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

C++は書かないのですがスタイル的には揃っていた方が自然かな、という程度でコメントしました。

ちなみに、イテレーターの引き算するとインデックスが求められたと思います。わざわざこのように書く必要はなさそうですが、ご参考までです。

        auto j = upper_bound(nums.begin() + i, nums.end(), nums[i-1]) - nums.begin();
        swap(nums[i-1], nums[j]);

Copy link
Owner Author

Choose a reason for hiding this comment

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

あ、確かにそうしてしまう手もありますね。こちらを使ってもいいかもしれません。
https://cpprefjp.github.io/reference/iterator/distance.html

class Solution {
public:
void nextPermutation(vector<int>& nums) {
auto it = is_sorted_until(nums.rbegin(), nums.rend());

Choose a reason for hiding this comment

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

イテレータであることはこの場合重要ではなく、とあるindexを指していることがわかるような変数名だと良いなと思いました。left や pivot でしょうか。it_next も同様です。

Copy link
Owner Author

Choose a reason for hiding this comment

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

実は最初itとit_nextをpivotとnextにしていたんですが、結局このような名前にしたところで実際のプログラムを見ないとどんな要素を指すイテレーターになっているかわからないだろうなという気がしてきて、だったらいっそのこと(autoで受けてしまっているのもあるし)型の情報を入れた方が読みやすいかなと思いこうしてみました。難しいところですが、、、

public:
void nextPermutation(vector<int>& nums) {
int i = nums.size() - 1;
while (i >= 1 && nums[i-1] >= nums[i]) {
Copy link

Choose a reason for hiding this comment

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

二項演算子の両側にはスペースを空けることが多いと思います。

参考までにスタイルガイドへのリンクを貼ります。

https://google.github.io/styleguide/cppguide.html#Horizontal_Whitespace

// Other binary operators usually have spaces around them, but it's
// OK to remove spaces around factors. Parentheses should have no
// internal padding.
v = w * x + y / z;
v = w*x + y/z;
v = w * (x + z);

上記のスタイルガイドは唯一絶対のルールではなく、複数あるスタイルガイドの一つに過ぎないということを念頭に置くことをお勧めします。また、所属するチームにより何が良いとされているかは変わります。自分の中で良い書き方の基準を持ちつつ、チームの平均的な書き方で書くことをお勧めいたします。


というか、もしかしたら最初に書いたコードは問題文の
The replacement must be in place and use only constant extra memory.
という条件を満たさないかもしれない(sortにO(log(nums.length))のメモリを使うかも?)
Copy link

Choose a reason for hiding this comment

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

仕様では空間計算量は規定されていないようです。
https://timsong-cpp.github.io/cppwp/n4950/sort#5

class Solution {
public:
void nextPermutation(vector<int>& nums) {
auto it = is_sorted_until(nums.rbegin(), nums.rend());

Choose a reason for hiding this comment

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

この関数、Python で解いたとき以前別の方から C++ だとこういうのありますね、という指摘を受けたんですが便利ですね。

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