算法之道--左右旋转字符串



定义字符串的左旋转操作:把字符串前面的若干个字符移动到字符串的尾部。
如把字符串abcdef左旋转2位得到字符串cdefab。
请实现字符串左旋转的函数,要求对长度为n的字符串操作的时间复杂度为O(n),空间复杂度为O(1)。 
 
 以下算法实现了可以做旋转和右旋转....
原理:
abcde123456
根据要旋转的位数k,把数组分成两子串,例如K=6,进行右旋转,则把字符串分成 abcde 和 123456(K位)
划分技巧:右旋转,后面子串位数为K,剩下做为前面子串;若是左旋转,前面子串位数为K,剩下做为后面子串
                如果上面 abcde123456 进行左旋转 K=6位,则字符串的划分是:abcde1(K位)  和 23456
接着对abcde和123456分别进行逆序操作结果:
edcba和654321
合并后成 
edcba654321
再整体逆序
123456abcde
 
优点: 3个reverse 操作都是线性操作,前两个时间复杂度和为0(n/2),最后一个整体逆序时间复杂度为0(n/2),总时间复杂度是O(n),比起普通的相同功能算法时间复杂度要低

package com.DataStructure;

import java.util.Scanner;

/*
 * 左旋转字符串
 */
public class XuanZhuanString
{
	public static void main(String[] args)
	{
		XuanZhuanString xz = new XuanZhuanString();
		Xuanzhuan(xz);
	}

	public static void Xuanzhuan(XuanZhuanString xz)
	{
		System.out.println("输入一行字符串:");
		Scanner input = new Scanner(System.in);
		char[] charArray = input.nextLine().toCharArray();
		System.out.println("输入要移动的位数:");
		int shiftNum = Integer.parseInt(input.nextLine());
		System.out.println("你输入的字符串为" + new String(charArray) + "要移动的位数为"
				+ shiftNum);
		// charArray = RightShift(shiftNum, charArray);
		charArray = LeftShift(shiftNum, charArray);
		System.out.println("移位结果为:" + String.valueOf(charArray));
		System.out.println("是否继续输入要移动的字符串?Y/N");
		String tag = input.next();
		if (tag.toLowerCase().equals("y"))
		{
			Xuanzhuan(xz);
		}
	}

	/**
	 * 
	 * @param shiftNum
	 *            偏移量
	 * @param charArray
	 *            源数组
	 * @return
	 */
	private static char[] RightShift(int shiftNum, char[] charArray)
	{
		charArray = reverse(charArray, 0, charArray.length - shiftNum - 1);
		charArray = reverse(charArray, charArray.length - shiftNum,
				charArray.length - 1);
		charArray = reverse(charArray, 0, charArray.length - 1);
		return charArray;
	}

	private static char[] LeftShift(int shiftNum, char[] charArray)
	{
		charArray = reverse(charArray, 0, shiftNum - 1);
		// 与右移不同在于下标的选取,这里是取前面shiftNum位
		charArray = reverse(charArray, shiftNum, charArray.length - 1);
		charArray = reverse(charArray, 0, charArray.length - 1);
		return charArray;
	}

	/**
	 * 
	 * @param charArray
	 *            要逆序排列的数组
	 * @param begin
	 * @param end
	 * @return
	 */
	private static char[] reverse(char[] charArray, int begin, int end)
	{
		char temp;
		for (; begin < end; end--, begin++)
		{
			temp = charArray[begin];
			charArray[begin] = charArray[end];
			charArray[end] = temp;
		}
		return charArray;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值