交换字符中的字符
给定一个长度为N的字符串S ,两个整数B和C ,任务是从头开始遍历字符,将一个字符与 C 之后的字符交换,即交换位置i和(i + C)%的字符ñ 。重复此过程B次,一次前进一个位置。你的任务是在B交换后找到最终的字符串。
例子:
Input : S = "ABCDEFGH", B = 4, C = 3;
Output: DEFGBCAH
Explanation:
after 1st swap: DBCAEFGH
after 2nd swap: DECABFGH
after 3rd swap: DEFABCGH
after 4th swap: DEFGBCAH
Input : S = "ABCDE", B = 10, C = 6;
Output : ADEBC
Explanation:
after 1st swap: BACDE
after 2nd swap: BCADE
after 3rd swap: BCDAE
after 4th swap: BCDEA
after 5th swap: ACDEB
after 6th swap: CADEB
after 7th swap: CDAEB
after 8th swap: CDEAB
after 9th swap: CDEBA
after 10th swap: ADEBC
天真的方法:
- 对于较大的B值,循环B次的幼稚方法,每次将第 i 个字符与第(i + C)%N 个字符交换将导致高 CPU 时间。
- 解决这个问题的诀窍是在每N次迭代后观察结果字符串,其中N是字符串S的长度。
- 同样,如果C大于或等于N ,它实际上等于C除以N的余数。
- 在此,让我们认为C小于N 。
有效的方法:
- 如果我们观察每N次连续迭代和交换后形成的字符串(我们称之为一次完整迭代),我们就可以开始得到一个模式。
- 我们可以发现字符串被分为两部分:长度为C的第一部分由S的前C个字符组成,第二部分由其余的字符组成。
- 这两个部分旋转了一些地方。第一部分在每次完整迭代时向右旋转(N % C)个位置。
- 第二部分在每次完整迭代时向左旋转C个位置。
- 我们可以通过将B除以N来计算完全迭代的次数f 。
- 因此,第一部分将向左旋转(N % C ) * f 。这个值可以超出C ,因此它实际上是( ( N % C ) * f ) % C ,即第一部分将旋转( ( N % C ) * f ) % C位置。
- 第二部分将向左旋转C * f个位置。因为,这个值可以超出第二部分的长度,即(N – C) ,它实际上是( ( C * f ) % ( N – C ) ) ,即第二部分将旋转( ( C * f ) % ( N – C ) )名额。
- 在f次完整迭代之后,可能还剩下一些迭代来完成B次迭代。该值为B % N ,它小于N 。我们可以在f次完整迭代后对这些剩余的迭代遵循朴素的方法来获得结果字符串。
Example:
s = ABCDEFGHIJK; c = 4;
parts: ABCD EFGHIJK
after 1 full iteration: DABC IJKEFGH
after 2 full iteration: CDAB FGHIJKE
after 3 full iteration: BCDA JKEFGHI
after 4 full iteration: ABCD GHIJKEF
after 5 full iteration: DABC KEFGHIJ
after 6 full iteration: CDAB HIJKEFG
after 7 full iteration: BCDA EFGHIJK
after 8 full iteration: ABCD IJKEFGH
下面是该方法的实现:
C++
// C++ program to find new after swapping
// characters at position i and i + c
// b times, each time advancing one
// position ahead
#include
using namespace std;
string rotateLeft(string s, int p)
{
// Rotating a string p times left is
// effectively cutting the first p
// characters and placing them at the end
return s.substr(p) + s.substr(0, p);
}
// Method to find the required string
string swapChars(string s, int c, int b)
{
// Get string length
int n = s.size();
// If c is larger or equal to the length of
// the string is effectively the remainder of
// c divided by the length of the string
c = c % n;
if (c == 0)
{
// No change will happen
return s;
}
int f = b / n;
int r = b % n;
// Rotate first c characters by (n % c)
// places f times
string p1 = rotateLeft(s.substr(0, c),
((n % c) * f) % c);
// Rotate remaining character by
// (n * f) places
string p2 = rotateLeft(s.substr(c),
((c * f) % (n - c)));
// Concatenate the two parts and convert the
// resultant string formed after f full
// iterations to a string array
// (for final swaps)
string a = p1 + p2;
// Remaining swaps
for(int i = 0; i < r; i++)
{
// Swap ith character with
// (i + c)th character
char temp = a[i];
a[i] = a[(i + c) % n];
a[(i + c) % n] = temp;
}
// Return final string
return a;
}
// Driver code
int main()
{
// Given values
string s1 = "ABCDEFGHIJK";
int b = 1000;
int c = 3;
// Get final string print final string
cout << swapChars(s1, c, b) << endl;
}
// This code is contributed by rag2127
Java
// Java Program to find new after swapping
// characters at position i and i + c
// b times, each time advancing one
// position ahead
class GFG {
// Method to find the required string
String swapChars(String s, int c, int b)
{
// Get string length
int n = s.length();
// if c is larger or equal to the length of
// the string is effectively the remainder of
// c divided by the length of the string
c = c % n;
if (c == 0) {
// No change will happen
return s;
}
int f = b / n;
int r = b % n;
// Rotate first c characters by (n % c)
// places f times
String p1 = rotateLeft(s.substring(0, c),
((n % c) * f) % c);
// Rotate remaining character by
// (n * f) places
String p2 = rotateLeft(s.substring(c),
((c * f) % (n - c)));
// Concatenate the two parts and convert the
// resultant string formed after f full
// iterations to a character array
// (for final swaps)
char a[] = (p1 + p2).toCharArray();
// Remaining swaps
for (int i = 0; i < r; i++) {
// Swap ith character with
// (i + c)th character
char temp = a[i];
a[i] = a[(i + c) % n];
a[(i + c) % n] = temp;
}
// Return final string
return new String(a);
}
String rotateLeft(String s, int p)
{
// Rotating a string p times left is
// effectively cutting the first p
// characters and placing them at the end
return s.substring(p) + s.substring(0, p);
}
// Driver code
public static void main(String args[])
{
// Given values
String s1 = "ABCDEFGHIJK";
int b = 1000;
int c = 3;
// get final string
String s2 = new GFG().swapChars(s1, c, b);
// print final string
System.out.println(s2);
}
}
Python3
# Python3 program to find new after swapping
# characters at position i and i + c
# b times, each time advancing one
# position ahead
# Method to find the required string
def swapChars(s, c, b):
# Get string length
n = len(s)
# If c is larger or equal to the length of
# the string is effectively the remainder of
# c divided by the length of the string
c = c % n
if (c == 0):
# No change will happen
return s
f = int(b / n)
r = b % n
# Rotate first c characters by (n % c)
# places f times
p1 = rotateLeft(s[0 : c], ((c * f) % (n - c)))
# Rotate remaining character by
# (n * f) places
p2 = rotateLeft(s[c:], ((c * f) % (n - c)))
# Concatenate the two parts and convert the
# resultant string formed after f full
# iterations to a character array
# (for final swaps)
a = p1 + p2
a = list(a)
# Remaining swaps
for i in range(r):
# Swap ith character with
# (i + c)th character
temp = a[i]
a[i] = a[(i + c) % n]
a[(i + c) % n] = temp
# Return final string
return str("".join(a))
def rotateLeft(s, p):
# Rotating a string p times left is
# effectively cutting the first p
# characters and placing them at the end
return s[p:] + s[0 : p]
# Driver code
# Given values
s1 = "ABCDEFGHIJK"
b = 1000
c = 3
# Get final string
s2 = swapChars(s1, c, b)
# Print final string
print(s2)
# This code is contributed by avanitrachhadiya2155
C#
// C# Program to find new after swapping
// characters at position i and i + c
// b times, each time advancing one
// position ahead
using System;
class GFG
{
// Method to find the required string
String swapChars(String s, int c, int b)
{
// Get string length
int n = s.Length;
// if c is larger or equal to the length of
// the string is effectively the remainder of
// c divided by the length of the string
c = c % n;
if (c == 0)
{
// No change will happen
return s;
}
int f = b / n;
int r = b % n;
// Rotate first c characters by (n % c)
// places f times
String p1 = rotateLeft(s.Substring(0, c),
((n % c) * f) % c);
// Rotate remaining character by
// (n * f) places
String p2 = rotateLeft(s.Substring(c),
((c * f) % (n - c)));
// Concatenate the two parts and convert the
// resultant string formed after f full
// iterations to a character array
// (for readonly swaps)
char []a = (p1 + p2).ToCharArray();
// Remaining swaps
for (int i = 0; i < r; i++)
{
// Swap ith character with
// (i + c)th character
char temp = a[i];
a[i] = a[(i + c) % n];
a[(i + c) % n] = temp;
}
// Return readonly string
return new String(a);
}
String rotateLeft(String s, int p)
{
// Rotating a string p times left is
// effectively cutting the first p
// characters and placing them at the end
return s.Substring(p) + s.Substring(0, p);
}
// Driver code
public static void Main(String []args)
{
// Given values
String s1 = "ABCDEFGHIJK";
int b = 1000;
int c = 3;
// get readonly string
String s2 = new GFG().swapChars(s1, c, b);
// print readonly string
Console.WriteLine(s2);
}
}
// This code is contributed by 29AjayKumar
Javascript
输出:
CADEFGHIJKB
时间复杂度:O(n)
空间复杂度:O(n)