字符串循环移动-高效优雅算法

命题:给定一个字符串S[0…N-1],要求把S的前k个字符移动到S的尾部,如把字符串“abcdef”前面的2个字符‘a’、‘b’移动到字符串的尾部,得到新字符串“cdefab”:即字符串循环左移k。

算法要求: 时间复杂度为 O(n),空间复杂度为 O(1)。


算法思考

可以采取的方法有:

直接来个嵌套循环移动,但是时间复杂度不满足,空间复杂度满足。不可取

三次拷贝,利用第三方空间。方便,时间复杂度满足,空间复杂度不满足。不可取

高效优雅的算法:一个离散数学中的式子:(X’Y’)’=YX

多说一句,之前学离散数学觉得只是学逻辑的,感觉在计算机中没多大关系,现在才知道,在算法上,利用离散数学的逻辑公式可以得到非常高效优雅的算法


算法演进

可能看到那个式子还是没有什么思路,那就是知识转化欠缺,但是通过多种练习,就可以很好地利用离散数学中的公式获得高效的算法。

演进:

 (X’Y’)’=YX

 如:abcdef

 X=ab X’=ba

 Y=cdef Y’=fedc

 (X’Y’)’=(bafedc)’=cdefab

 时间复杂度O(N),空间复杂度O(1)


java代码实现

	/**反转。把字符数组从from位置到to位置的数反转*/
	static void revertStr(char[] str, int from, int to){
		if(to - from < 1){
			return;
		}
		for(int i = from; i < (to + from + 1)/2;i++){
			swapChar(str,i,to -(i - from));
		}
	}
	
	static void swapChar(char[] s, int i, int j) {
		char temp = s[i];
		s[i] = s[j];
		s[j] = temp;
	}
	
	/**字符数组str中moveStrHead位置到moveStrEnd位置的字符向右循环移动moveLength位*/
	static void circleLeftMove(char[] str, int moveStrHead, int moveStrEnd, int moveLength){
		revertStr(str, moveStrHead, moveStrEnd);
		revertStr(str, moveStrEnd+1, moveStrEnd + moveLength);
		revertStr(str, moveStrHead, moveStrEnd + moveLength);
	}

测试代码:

	public static void main(String[] args) {
		String test = "123456789";
		char[] charArray = test.toCharArray();
		circleLeftMove(charArray, 0, 2, 2);
		System.out.println(charArray);
	}

输出结果:

451236789


时间复杂度与空间复杂度分析

时间复杂度是:别看调用了三次revertStr()方法,实际上,他们是线性的,所以时间复杂度是O(n)

空间复杂度:明显是O(1)


若要实现其他移动方式,那么对代码稍加改动即可


若有更高效的算法,请留言告知,再次感谢

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
BF算法(Brute-Force算法),也称为朴素匹配算法,是一种简单直观的字符串匹配算法。它的基本思想是从主串的第一个字符开始,依次与模式串的每个字符进行比较,如果匹配成功,则继续比较下一个字符,否则主串指针后移一位,重新开始匹配。这个过程类似于暴力破解密码的过程,因此也被称为暴力匹配算法。 下面是BF算法的C语言实现: ```c #include <stdio.h> #include <string.h> int BF(char* s, char* p) { int i = 0, j = 0; int s_len = strlen(s); int p_len = strlen(p); while (i < s_len && j < p_len) { if (s[i] == p[j]) { i++; j++; } else { i = i - j + 1; j = 0; } } if (j == p_len) { return i - j; } else { return -1; } } int main() { char s[] = "hello world"; char p[] = "world"; int pos = BF(s, p); if (pos != -1) { printf("匹配成功,位置为:%d\n", pos); } else { printf("匹配失败\n"); } return 0; } ``` 在上面的代码中,BF函数接受两个参数,分别是主串s和模式串p。在函数中,我们使用两个指针i和j分别指向主串和模式串的第一个字符,然后依次比较它们的字符是否相等。如果相等,则继续比较下一个字符,否则主串指针后移一位,重新开始匹配。如果模式串匹配成功,则返回匹配的位置,否则返回-1。 需要注意的是,BF算法的时间复杂度为O(m*n),其中m和n分别为主串和模式串的长度。因此,当主串和模式串的长度较大时,BF算法的效率会比较低。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值