Dalam masalah ini, kami akan melakukan pertanyaan terbalik M pada rentetan yang diberikan mengikut nilai tatasusunan.
Pendekatan naif untuk menyelesaikan masalah adalah untuk membalikkan setiap segmen rentetan mengikut nilai tatasusunan yang diberikan.
Pendekatan yang dioptimumkan menggunakan logik bahawa apabila kita membalikkan subrentetan yang sama dua kali, kita mendapat rentetan asal.
Pernyataan masalah − Kami telah memberikan rentetan alfa yang mengandungi aksara abjad. Selain itu, kami telah memberikan tatasusunan arr[] saiz M yang mengandungi integer positif. Kita perlu melakukan operasi M pada rentetan yang diberikan dan mengembalikan rentetan akhir.
Dalam setiap operasi, kita perlu mengambil arr[i] dan menghormati subrentetan arr[i] kepada N − arr[i] + 1.
示例例子
输入
alpha = "pqrst"; arr = {2, 1};
输出
tqrsp
Penjelasan
执行第一个查询后,字符串变为 'psrqt'。
执行第二个查询后,我们得到了 'tqrsp'。
输入
− alpha = "pqrst"; arr = {1, 1};
输出
− ‘pqrst’
Penjelasan − 如果我们对同一个查询执行偶数次,我们会得到相同的字笎东。
输入
− alpha = "pqrst"; arr = {1, 1, 1};
输出
− ‘tsrqp’
Penjelasan − Jika kita melakukan pertanyaan yang sama untuk bilangan ganjil, kita mendapat rentetan terbalik.
Pendekatan 1Algoritma
步骤 1 - 开始遍历查询数组。
第2步 - 使用arr[p] - 1初始化'kiri'变量。
Langkah 3 − Mulakan pembolehubah 'betul' dengan str_len − arr[p] + 1.
Langkah 4 − Gunakan kaedah reverse() untuk membalikkan subrentetan daripada penunjuk kiri ke penunjuk kanan.
Contoh#include <bits/stdc++.h> using namespace std; void reverseStrings(string &alpha, int str_len, vector<int> &arr, int arr_len){ // Traverse all queries for (int p = 0; p < arr_len; p++){ // Get starting pointer int left = arr[p] - 1; // Ending pointer int right = str_len - arr[p] + 1; // Reverse the string reverse(alpha.begin() + left, alpha.begin() + right); } } int main(){ int str_len = 5; string alpha = "pqrst"; int arr_len = 2; vector<int> arr = {2, 1}; reverseStrings(alpha, str_len, arr, arr_len); cout << "The string after performing queries is " << alpha << endl; return 0; }
The string after performing queries is tqrsp
Kerumitan ruang − O(1) kerana kami tidak menggunakan sebarang ruang dinamik.
方法二
Algoritma
步骤 1 - 初始化长度等于字符串长度的 'cnt' 列表,用 0 存储特定等于字符串长度的 'cnt' 列表,用 0 存储特定索厬厬的。
Langkah 2 − Lintas tatasusunan pertanyaan yang diberikan dan ambil penunjuk kiri dan kanan rentetan mengikut pertanyaan semasa.
Langkah 3 − Laksanakan juga fungsi changeRange() untuk mengemas kini senarai ‘cnt’ mengikut penunjuk kiri dan kanan pertanyaan semasa.
Langkah 3.1 − Dalam fungsi changeRange(), naikkan nilai pada indeks 'kiri' dalam senarai 'cnt'.
第3.2步 - 减小“cnt”列表中位于“kanan + 1”指针右侧的所有值。
Di sini, kami perlu menambah semua nilai senarai 'cnt' sebanyak 1 dalam julat [kiri, kanan]. Jadi, kami hanya menambah cnt[kiri] sebanyak 1 kerana mengambil jumlah awalan akan menambah semua nilai sebanyak 1, iaitu di sebelah kanan indeks 'kiri'. Selain itu, kami tidak mahu menambah nilai cnt antara indeks [right, str_len], jadi kami telah mengurangkannya sebanyak 1 kerana jumlah awalan akan meningkatkannya sebanyak 1.
Langkah 4 − Seterusnya, laksanakan fungsi getPrefixSum() untuk mengira jumlah awalan senarai 'cnt'.
Langkah 4.1 − Dalam fungsi getPrefixSum(), lintasi rentetan dan tambahkan nilai elemen sebelumnya pada elemen semasa.
步骤 5 - 接下来,以逆序遍历‘cnt’列表。如果当前元素是奇数,则将序遍历‘cnt’列表。如果当前元素是奇数,则将劬父子了
步骤 6 - 用0初始化‘p’和‘q’,按照原始顺序遍历‘cnt’列表。
步骤 7 − 如果‘cnt’列表中的当前元素是奇数,则使用tmp[q]更新alpha[p]。
Langkah 8 − Pada penghujung, kembalikan rentetan alfa.
Contoh#include <iostream> #include <vector> using namespace std; void changeRange(vector<int>& cnt, int left, int right) { // Increase the value of the left index cnt[left]++; // Decrement value for all indexes after the right index if (right + 1 < cnt.size()) cnt[right + 1]--; } void getPrefixSum(vector<int>& cnt) { // Calculate prefix sum for (int p = 1; p < cnt.size(); p++) { cnt[p] += cnt[p - 1]; } } string reverseStrings(string alpha, int str_len, vector<int>& arr, int arr_len) { vector<int> cnt(str_len, 0); // Traverse the array for (int p = 0; p < arr_len; p++) { int left = arr[p] <= (str_len + 1) / 2 ? arr[p] - 1 : str_len - arr[p]; int right = arr[p] <= (str_len + 1) / 2 ? str_len - arr[p] : arr[p] - 1; // Changes index ranges between left and right changeRange(cnt, left, right); } getPrefixSum(cnt); string tmp; // Store characters with the odd reversal in the reverse order in the tmp string for (int p = cnt.size() - 1; p >= 0; p--) { if (cnt[p] % 2 != 0) tmp.push_back(alpha[p]); } int p = 0, q = 0; // For even reversal, pick the character from the original string. // For odd reversal, pick the character from the temp string. for (p = 0; p < cnt.size(); p++) { if (cnt[p] % 2 != 0) alpha[p] = tmp[q++]; } // Answer string return alpha; } int main() { int str_len = 5; string alpha = "pqrst"; int arr_len = 2; vector<int> arr = { 2, 1 }; alpha = reverseStrings(alpha, str_len, arr, arr_len); cout << "The string after performing queries is: " <<alpha << endl; return 0; }
The string after performing queries is: tqrsp
空间复杂度 - 使用 'cnt' 列表为 O(N)。
在第一种方法中,我们使用了reveres()方法来执行给定字符串上的所有查诬不一们京京一们一们一们一们一们了使用了前缀和技术来计算特定索引在反转中出现的次数。
Atas ialah kandungan terperinci Terjemahan: Untuk pertanyaan M, terbalikkan julat rentetan yang diberikan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!