左旋字符串 - wtstengshen/blog-page GitHub Wiki

命题要求:左旋字符串的定义是,例如 123abcde 这个字符串,把123左旋后的结果是abcde123,时间复杂度为O(n),空间复杂度为O(1);

思路1. 暴力循环

1,首先把1放到临时变量tmp;

2,把23abcde分别向前移动一位,然后把1(tmp里的只)放到结尾;

3,一次循环23;

这种方式确实可以解决问题,最先想到的也是这个方法,具体代码不在描述,放弃;

思路2. 使用两个指针变量,移动因为要求空间复杂度为O(1),所以可以考虑使用连个指针变量p1,p2;

p1指向123的1,p2指向a,然后对两个指针指向的内容进行替换,

例如;

1, p1-->1,p2-->a,p1和p2指向的内容互换位置,这时变为 a23 1bcde;然后 p1++,p2++;

2, p1-->2,p2-->b, 互换内容,变为 ab3 12cde;然后依次循环;

这个会有个问题,当循环到 abc 123de的时候,p1指向1,p2指向d,这个时候在像刚才那样循环,p2就溢出了,

这个时候,需要我们进行特殊处理:我们只需要把d和e向前循环替换就可以了

例如:

abc123de p1-->1,p2-->d,把d分别向前移动到p1指向的位置:

abc123de -> abc12d3e -> abc1d23e -> abcd123e

然后把e和d一样向前移动;

代码如下:

       /**
	 * 时间o(n),空间o(1), 左旋数组,省略参数校验
	 * 
	 * @param ch
	 * @param m
	 * @return
	 */
	public char[] leftRotate1(char[] ch, int m) {

		int size = ch.length;

		// 初始化两个指针
		int p1 = 0;
		int p2 = m;

		// 1,第一层循环,进行循环处理,向后校验元素,处理能够被整除的循环
		int k = (size - m) - size % m;

		while (k-- != 0) {
			this.swap(ch, p1, p2);
			p1++;
			p2++;
		}

		// 2,处理最后结尾,剩下的数据
		int n = size - p2;
		while (n-- != 0) {
			int i = p2;
			while (i > p1) {
				this.swap(ch, i, i - 1);
				i--;
			}
			p1++;
			p2++;
		}

		return ch;
	}
	
	/**
	 * 交换位置
	 * 
	 * @param ch
	 * @param i
	 * @param j
	 */
	private void swap(char[] ch, int i, int j) {
		char tmp = ch[i];
		ch[i] = ch[j];
		ch[j] = tmp;
	}
思路3.翻转方法

还是刚才的例子:把123abcde 分成两个部分:123 和 abcde

1,把123进行翻转,结果是 321 ;

2,把abcde进行翻转,结果是edcba ;

3,然后把两个部分组合,进行翻转,既 3 2 1 e d c b a 翻转为a b c d e 1 2 3;

其中,在《编程珠玑》上也有这样一个类似的问题的描述

说明图片

代码如下:

       /**
	 * 时间o(n),空间o(1),把字符串分成两组,分别进行翻转,然后对整体进行翻转
	 * 
	 * @param ch
	 * @param m
	 * @return
	 */
	public char[] leftRotate2(char[] ch, int m) {

		int size = ch.length;

		this.invert(ch, 0, m - 1);
		this.invert(ch, m, size - 1);
		this.invert(ch, 0, size - 1);

		return ch;
	}

	/**
	 * 翻转数组
	 * 
	 * @param ch
	 * @param begin
	 * @param end
	 */
	private void invert(char[] ch, int begin, int end) {

		while (begin != end) {
			this.swap(ch, begin, end);
			begin++;
			end--;
		}
	}

本次博客总结左旋字符串翻转的几个常用的方法,欢迎拍砖;

作者 @悠悠小竹子

博客 iocoding