现在的位置: 首页 > 综合 > 正文

左旋字符串

2013年07月19日 ⁄ 综合 ⁄ 共 1351字 ⁄ 字号 评论关闭

输入n与数组t,正数表示数组往左移动n位,负数表示数组往右移动n位。

要求时间为n阶,空间为1

来自于结构之法的作者,较好的算法是:

将一个字符串分成两部分,X和Y两个部分,在字符串上定义反转的操作X^T,即把X的
所有字符反转(如,X="abc",那么X^T="cba"),那么我们可以得到下面的结论:
(X^TY^T)^T=YX。显然我们这就可以转化为字符串的反转的问题了。

其实这种运算在矩阵的翻转求逆等运算中多得是,和牛人的差距就是怎么都联系不起来。。。。汗

琢磨了半天自己想了个类似于辗转相减法的实现,和原pdf中的算法2差不多,java代码如下:

/**
	 * 实现左移或者或者右移数组n位
	 * 时间复杂度为O(n),空间为O(1)
	 * @param t   要移动的数组
	 * @param n   n为数组要移动的位数,n>0 左移,n<0右移
	 * @return
	 */
	public <T> T[] rotate(T[] t,int n){
		if(n==0)
			return t;
		boolean right = false;
		if(n<0){//需要往右移动
			n = Math.abs(n);
			right = true;
		}
			
		if(n>t.length){//超过长度取模,因为移一个数组长度等于没移
			n = n%t.length;
		}
		if(right){
			n = t.length-n;//往右移n位等于往左移动t.length-n位
		}
		//分为2个子序列,移动到尾部的子序列A和要移动到头部的子序列B
		int start = 0;//序列A的头部和尾部索引
		int end = n-1;
		int aLength = end -start+1;
		int bLength = t.length- n;//序列B的长度 
		
		T temp;//用来交换值的临时变量
		
		while(true){
			if(end-start+1==bLength){//类似于2整数辗转相减法,所以相等条件可以达到
				for(int i=start;i<=end;i++){
					temp=t[i];t[i]=t[i+aLength];t[i+aLength]=temp;//java值传递,
										//不可以调用函数互换值,形参互换对实参无意义
				}
				break;
			}else if(aLength<bLength){//A序列长度小于B序列
				for(int i=start;i<=end;i++){//那就将B序列中起点开始的等于A序列长度
					temp=t[i];t[i]=t[i+aLength];t[i+aLength]=temp;//的序列和A互换
				}							//将B序列部分值放到应该放到位置
				start = end+1;				//同时B序列的长度减少了
				end = start+aLength-1;
				bLength = bLength - aLength;
			}else{//A序列的长度大于B序列,那就将A序列和B序列长度相等的部分和B序列互换
				for(int i=end+1;i<end+1+bLength;i++){//这样可以将B序列放到应该放的
					temp=t[i];t[i]=t[i-aLength];t[i-aLength]=temp;//位置
				}
				start = start+bLength;//同时A序列的长度减少了,A序列中和B互换的子序列
				aLength = aLength-bLength;//变成要左移的到指定位置的序列
			}
		}
			
		
		return t;
	}

抱歉!评论已关闭.