Skip to content

621. Task Scheduler - #116

Open
kazuki-official wants to merge 1 commit into
mainfrom
621-task-scheduler
Open

621. Task Scheduler#116
kazuki-official wants to merge 1 commit into
mainfrom
621-task-scheduler

Conversation

@kazuki-official

Copy link
Copy Markdown
Owner

Comment thread memo.md
}

std::priority_queue<std::pair<int, char>> executables;
for (const auto& [label, num_tasks] : label_to_num_tasks) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

こちらのコメントをご参照ください。
hemispherium/LeetCode_Arai60#10 (comment)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

ありがとうございます。今回は値渡しの方がよさそうですね

@nodchip

nodchip commented Jul 9, 2026

Copy link
Copy Markdown

書いてみたところ、延々とバグってひどいコードになってしまいました。供養のために掲載します。

class Solution {
public:
    int leastInterval(vector<char>& tasks, int n) {
        map<char, int> task_to_count;
        for (char task : tasks) {
            ++task_to_count[task];
        }

        map<int, vector<char>> remaining_tasks;
        for (auto [task, count] : task_to_count) {
            remaining_tasks[count].push_back(task);
        }

        vector<int> last_clocks(128, std::numeric_limits<int>::min() / 2);
        int clock = 0;
        while (!remaining_tasks.empty()) {
            ++clock;

            // for (const auto& [count, tasks] : remaining_tasks) {
            //     std::cout << count;
            //     for (char task : tasks) {
            //         std::cout << " " << task;
            //     }
            //     std::cout << std::endl;
            // }

            ComsumeTask(remaining_tasks, last_clocks, clock, n);
        }

        return clock;
    }

    void ComsumeTask(
        map<int, vector<char>>& remaining_tasks, vector<int>& last_clocks,
        int clock, int n) {
        for (auto rit = remaining_tasks.rbegin(); rit != remaining_tasks.rend(); ++rit) {
            int count = rit->first;
            for (auto it = rit->second.begin(); it != rit->second.end(); ++it) {
                char task = *it;
                // std::cout << task << "?" << std::endl;
                if (clock - last_clocks[task] <= n) {
                    continue;
                }

                // std::cout << task << std::endl;

                swap(*it, rit->second.back());
                rit->second.pop_back();
                if (rit->second.empty()) {
                    remaining_tasks.erase(count);
                }
                if (count > 1) {
                    remaining_tasks[count - 1].push_back(task);
                }
                last_clocks[task] = clock;
                return;
            }
        }

        // std::cout << "idle" << std::endl;
    }
};

@kazuki-official

Copy link
Copy Markdown
Owner Author

書いてみたところ、延々とバグってひどいコードになってしまいました。供養のために掲載します。

class Solution {
public:
    int leastInterval(vector<char>& tasks, int n) {
        map<char, int> task_to_count;
        for (char task : tasks) {
            ++task_to_count[task];
        }

        map<int, vector<char>> remaining_tasks;
        for (auto [task, count] : task_to_count) {
            remaining_tasks[count].push_back(task);
        }

        vector<int> last_clocks(128, std::numeric_limits<int>::min() / 2);
        int clock = 0;
        while (!remaining_tasks.empty()) {
            ++clock;

            // for (const auto& [count, tasks] : remaining_tasks) {
            //     std::cout << count;
            //     for (char task : tasks) {
            //         std::cout << " " << task;
            //     }
            //     std::cout << std::endl;
            // }

            ComsumeTask(remaining_tasks, last_clocks, clock, n);
        }

        return clock;
    }

    void ComsumeTask(
        map<int, vector<char>>& remaining_tasks, vector<int>& last_clocks,
        int clock, int n) {
        for (auto rit = remaining_tasks.rbegin(); rit != remaining_tasks.rend(); ++rit) {
            int count = rit->first;
            for (auto it = rit->second.begin(); it != rit->second.end(); ++it) {
                char task = *it;
                // std::cout << task << "?" << std::endl;
                if (clock - last_clocks[task] <= n) {
                    continue;
                }

                // std::cout << task << std::endl;

                swap(*it, rit->second.back());
                rit->second.pop_back();
                if (rit->second.empty()) {
                    remaining_tasks.erase(count);
                }
                if (count > 1) {
                    remaining_tasks[count - 1].push_back(task);
                }
                last_clocks[task] = clock;
                return;
            }
        }

        // std::cout << "idle" << std::endl;
    }
};

clockをインクリメントしながら実際の動作に近い形で実装したのですね。ぱっと見変なところはないのですが、バグっているのですね...

@nodchip

nodchip commented Jul 10, 2026

Copy link
Copy Markdown

clockをインクリメントしながら実際の動作に近い形で実装したのですね。ぱっと見変なところはないのですが、バグっているのですね...

説明足らずで申し訳ありません。上記のコードは何度か修正して AC をもらったものです。途中、

if (rit->second.empty()) {
    remaining_tasks.erase(count);
}

が抜けており、無限ループしたりしていました。

あと、 rit と it の変数名がひどいと感じています。

@kazuki-official

Copy link
Copy Markdown
Owner Author

ああ、そういうことですね。
自分では思い付いてなかった解法なので勉強になりました。

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants