透過重新排列子字串的字元來最大化迴文的值
在這個問題中,我們需要找到透過重新排列給定字串的任何子字串的字元來獲得的最大回文字串。
我們將使用位掩碼來解決最大回文子字串問題。如果任何子字串的位掩碼為0,則它包含所有字元的偶數個。因此,我們可以使用該子字串的字元生成迴文字串,我們需要找到其中最大的迴文字串。
問題陳述 - 我們得到一個包含N個數字字元的字串。我們需要找到透過重新排列給定字串的任何子字串的字元來獲得的最大回文字串。
示例
輸入
alpha = "81343451";
輸出
4315134
解釋 - 我們可以取子字串'1343451',並透過重新排列其字元使其成為迴文。
輸入
alpha = "12345";
輸出
5
解釋 - 我們可以使用任何子字串生成的最大的迴文字串是5。
輸入
alpha = "65433456";
輸出
"65433456";
方法一
在這種方法中,我們將使用位掩碼。我們將有一個長度為10的二進位制字串,二進位制字串的每個字元代表從0到9的數字。如果二進位制字串中任何字元的值為'1',則相關數字在子字串中出現奇數次。
如果位掩碼只包含一個'1',我們可以選擇一個子字串透過重新排列其字元來形成迴文子字串,因為它只包含一個奇數頻率的數字。
因此,我們將找到所有位掩碼為0或只包含一個'1'的字串,將它們轉換為迴文,並取最大值作為答案。
演算法
步驟1 - 定義大小為1025 (210 + 1) 的列表來儲存掩碼索引,並將'bitMask'初始化為0。同時,將答案初始化為'0'以儲存最大有效的迴文字串。
步驟2 - 開始遍歷數字字串。
步驟3 - 將1左移字元值(可以在0到9之間),並將其與'bitMask'值進行異或運算。
步驟4 - 如果'bitMask'為0,則子字串包含所有頻率為偶數的字元。因此,執行maxValue()函式以透過重新排列子字串的字元來獲得最大回文字串。
步驟4.1 - 在maxValue()函式中,定義'freq'對映來儲存子字串中字元的頻率。
步驟4.2 - 將'temp'和'odd'初始化為空字串。
步驟4.3 - 從末尾開始遍歷對映。如果字元的頻率為奇數,則將字元儲存在odd中。否則,將freq/2個字元追加到'temp'字串。
步驟4.4 - 反轉temp字串。
步驟4.5 - 在追加temp、odd和反轉後的字串之後返回結果字串。
步驟5 - 執行getMaximumString()函式以從答案和maxValue()函式返回的值中獲取最大字串。
步驟5.1 - 在getMaximumString()函式中返回長度最大的字串。如果兩個字串的長度相同,則返回字典序最大的字串。
步驟5.2 - 將最大字串儲存在'answer'中。
步驟6 - 我們需要分別切換所有位並獲得最大答案。因此,開始遍歷0到9的數字。
步驟7 - 在迴圈中,將1左移數字值,並將其與'bitMask'值進行異或運算。
步驟8 - 如果'newBitMask'為0,則子字串只包含一個奇數頻率的字元。因此,我們可以重新排列子字串以使其成為迴文。將最大子字串儲存在'answer'中。
步驟9 - 如果'newBitMask'已經存在於'index'陣列中,則從index[newbitMask] + 1到p索引取一個子字串,生成最大回文字串,並將最大字串儲存在'answer'變數中。
步驟10 - 如果'bitMask'不存在於'index'陣列中,則將其值更新為'p'索引。
步驟11 - 返回'answer'。
示例
#include <bits/stdc++.h>
using namespace std;
// Rearrange characters to get the largest string
string maxValue(string &str, int start, int end) {
map<char, int> freq;
// Count frequency of each digit
for (int p = start; p <= end; p++) {
freq[str[p]]++;
}
string temp = "", odd = "";
// Traverse map in reverse order
for (auto iter = freq.rbegin(); iter != freq.rend(); iter++) {
// Take 1 odd number
if (iter->second % 2 != 0) {
odd = iter->first;
} else {
temp += string(iter->second / 2, iter->first);
}
}
// Reverse temp string to append it after the odd character
string rev = temp;
reverse(rev.begin(), rev.end());
// Return the largest palindromic string
return temp + odd + rev;
}
// Get maximum string
string getMaximumString(string temp1, string temp2) {
if (temp1.size() > temp2.size())
return temp1;
if (temp2.size() > temp1.size())
return temp2;
if (temp1 > temp2) {
return temp1;
}
return temp2;
}
string getMaximumPalindrome(string &alpha) {
vector<int> index(1025, -1);
int bitMask = 0, len = alpha.size();
string answer = "0";
// Iterate over the string
for (int p = 0; p < len; p++) {
// Toggle the bit corresponding to the digit in the bitMask
bitMask ^= (1 << (alpha[p] - '0'));
// When bitMask is 0, all characters appear an even number of times
if (bitMask == 0) {
// Get maximum palindromic string using characters from 0 to p
answer = getMaximumString(answer, maxValue(alpha, 0, p));
}
// Change all bits and get a maximum answer
for (int q = 0; q <= 9; q++) {
// Toggle the mask
int newbitMask = bitMask;
newbitMask ^= (1 << q);
// If all characters appear even a number of times
if (newbitMask == 0) {
answer = getMaximumString(answer, maxValue(alpha, 0, p));
}
// If the new mask has already visited
else if (index[newbitMask] != -1) {
answer = getMaximumString(answer, maxValue(alpha, index[newbitMask] + 1, p));
}
}
// Updated the visited index of the mask
if (index[bitMask] == -1) {
index[bitMask] = p;
}
}
return answer;
}
int main() {
string alpha = "81343451";
cout << "The maximum palindromic substring that we can create is "
<<getMaximumPalindrome(alpha);
return 0;
}
輸出
The maximum palindromic substring that we can create is 4315134
時間複雜度 - O(N*N),用於遍歷字串並生成最大回文子字串。
空間複雜度 - O(N),用於在對映中儲存字元的頻率以及在答案中儲存最大字串。
位掩碼是一種非常強大的技術,可以使任何解決方案更高效。如果我們使用樸素的方法來解決問題,則需要O(N*N)的時間來查詢所有子字串,以及O(N)的時間來重新排列子字串的字元。因此,我們用O(N*N)的時間複雜度解決了這個問題,而不是O(N3)。
資料結構
網路
關係資料庫管理系統 (RDBMS)
作業系統
Java
iOS
HTML
CSS
Android
Python
C語言程式設計
C++
C#
MongoDB
MySQL
Javascript
PHP