左旋轉字符串(字符串)

左旋轉字符串(字符串)題目:定義字符串的左旋轉操作:把字符串前面的若干個字符移動到字符串的尾部。如把字符串abcdef左旋轉2位得到字符串cdefab。請實現字符串左旋轉的函數。要求時間對長度爲n的字符串操作的複雜度爲O(n),輔助內存爲O(1)。


思路: 由於兩個要求,導致編碼很麻煩了, 思路就是成段的和相鄰的字符交換

abcdef 2

那麼就用ab 和 cd交換變成 cdabef

再用ab和 ef交換 變成 cdefab ,就完成了


但是出現abcdefg 3

abc 和def 交換變成 defabcg

但是這個時候abc 和g沒法交換了, 那麼我們就反着旋轉就ok了, 比如 讓g 和 c交換變成 abgc

g 和b交換變成agbc, 

g和a交換變成gabc;就達到目的了


編碼的時候注意交換的方向隨着能否交換而不停的改變


abcdef 2

第一次remain = (6 - 2) - 2 = 2

最終當remain == 0的時候停止循環就行了


#include <cstring>
#include <cstdio>

using namespace std;

template<class T>
void swap(T &x, T &y)
{
	char tmp;
	tmp = x;
	x = y;
	y = tmp;
}
void leftToRight(char s[], int start, int len)
{
	for(int i = start; i < len + start; i++)
	{
		swap(s[i], s[i + len]);
	}
}
void rightToLeft(char s[], int start, int len)
{
	for(int i = start; i > start - len; i--)
		swap(s[i], s[i - len]);
}

int solve(char s[], int m)           // O(1)的空間複雜度,o(n)的時間複雜度, 旋轉字符串
{
	const int len = strlen(s);
	int remain = len - m;

	int i = 0;
	bool dir = true;    //朝右
	while(remain)
	{
		if(dir)
		{
			if(m <= remain)
			{
				remain -= m;
				leftToRight(s, i, m);
				i += m;
			}
			else
			{
				dir = !dir;
				i = i + m + remain - 1;
				swap(m, remain);
			}
		}
		else
		{
			if(m <= remain)
			{
				remain -= m;
				rightToLeft(s, i, m);
				i -= m;
			}
			else
			{
				dir = !dir;
				i = i - remain - m + 1;
				swap(m, remain);
			}
		}
	}
	for(int i = 0; i < len; i++)
		printf("%c", s[i]);
	puts("");
	return 0;
}

int main()
{
	char s[] = "abcdefgabcdeft";
	solve(s, 4);
	return 0;
}


當我寫完程序後發現時間空間複雜度多了m, 更不好的是編碼麻煩; 然後我就發現網上有一個更牛逼的解法


abcdef 2

第一步: ba

第二步: fedc

然後見可以bafedc

最後就cdefab



這個相對於第一種方法太好編碼了就略了



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章