C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++でリストを左にK要素だけ回転させる方法

数値のリストが与えられたとき、そのリストを左方向に k 要素分だけ回転させるメソッドを実装する問題を考えてみましょう。

例えば、入力が [5,4,7,8,5,6,8,7,9,2]、k = 2 の場合、出力は [8,5,6,8,7,9,2,5,4,7] となります。先頭の2要素(5と4)が末尾に移動し、残りの要素が前に詰められるイメージです。

解決のアプローチ

この問題は、以下の手順で解くことができます。

  • 結果を格納するための配列 ret を定義します。
  • n := nums のサイズ(要素数)とします。
  • k := k mod n として、k が n 以上の場合に備えます(k が n の倍数なら回転しても元のままになるため)。
  • i := k から開始し、i < n の間 i を1ずつ増やしながらループ処理を行います。
    • ret の末尾に nums[i] を挿入します。
  • i := 0 から開始し、i < k の間 i を1ずつ増やしながらループ処理を行います。
    • ret の末尾に nums[i] を挿入します。
  • ret を返します。

つまり、まず k 番目以降の要素をすべて新しい配列に追加し、その後に先頭から k 個の要素を後ろに追加することで、左回転を実現しています。

C++での実装例

以下のコードを見ると、より理解しやすくなります。

#include <bits/stdc++.h>
using namespace std;
void print_vector(vector<auto> v) {
   cout << "[";
   for (int i = 0; i < v.size(); i++) {
      cout << v[i] << ", ";
   }
   cout << "]" << endl;
}
class Solution {
   public:
   vector<int> solve(vector<int>& nums, int k) {
      vector <int> ret;
      int n = nums.size();
      k %= n;
      for(int i = k; i < n; i++){
         ret.push_back(nums[i]);
      }
      for(int i = 0; i < k; i++){
         ret.push_back(nums[i]);
      }
      return ret;
   }
};
main(){
   Solution ob;
   vector<int> v = {5,4,7,8,5,6,8,7,9,2};
   print_vector(ob.solve(v, 3));
}

入力

{5,4,7,8,5,6,8,7,9,2}, 2

出力

[8, 5, 6, 8, 7, 9, 2, 5, 4, 7]

計算量について

このアルゴリズムの時間計算量は O(n) です。リストの全要素を一度ずつ走査するためです。また、新しい配列 ret を使用しているため、空間計算量も O(n) となります。

補足:in-place での回転

追加メモリを使わずに元の配列を直接変更したい場合は、「全体を反転 → 前半部分を反転 → 後半部分を反転」という三段階の反転テクニックを使うことで、O(1) の追加空間で左回転を実現できます。これは面接などでもよく聞かれる応用テクニックなので、覚えておくと便利です。

  1. C++でリンクリストをフラット化する方法【ソート済みリストの統合】

    この問題では、right と down という2つのポインタを持つノードで構成されるリンクリストが与えられます。 rightポインタ: メインとなるリンクリストをつなぐためのポインタです。 downポインタ: そのノードから始まるサブリンクリストをつなぐためのポインタです。 すべてのリンクリストはそれぞれソート済みであるものとします。求められているのは、これらの複数のリンクリストを1本のリストにまとめる(フラット化する)プログラムを作成することです。そして、結果として得られるリストもソート済みの状態になっていなければなりません。 問題の例 入力: 出力: 1-> 9->

  2. C++のstd::list::sort()でリストをソートする方法

    C++標準ライブラリによるソートの概要この記事では、C++の標準ライブラリを活用して配列や連結リスト(リンクリスト)をソートする方法について解説します。C++にはさまざまな用途に対応する多数のライブラリが標準で用意されており、ソート機能もその一つです。std::list::sort()は、リストの要素を昇順に並べ替えるメンバ関数です。この関数は安定ソート(stable sort)であるため、値が等しい要素同士の相対的な順序は保持されます。要素の比較には、デフォルトでoperator<が使用されます。サンプルコード#include <iostream> #include <li