算法分析_左右字符串交换

左右字符串交换

题目描述

给定一个字符串str和长度leftsize,请把str左侧leftsize的部分和右部分做整体交换。要求额外空间复杂度 O ( 1 ) O(1) O(1)

进阶:如果交换代价很昂贵,有没有更好一些方法。

示例1

输入:abcdefg	leftsize=3
返回值:defgabc

解题思路一

  • 左边字符串逆序
  • 右边字符串逆序
  • 字符串整体逆序
原字符串:abcdefg
左边字符串逆序:cbadefg
右边字符串逆序:cbagfed
整体逆序:defgabc

代码如下:

//解法一:三次逆序
public static String change(char[] str, int lSize){
    int length = str.length;
    //左边字符串逆序,右边字符串逆序,然后整体逆序
    //就可以实现左边字符串与右边字符串交换位置
    reverse(str, 0, lSize-1);
    reverse(str, lSize, length-1);
    reverse(str, 0, length-1);
    return new String(str);
}

public static void reverse(char[] str, int start, int end){
    while (start < end){
        char temp = str[start];
        str[start++] = str[end];
        str[end--] = temp;
    }
}

解题思路二

先判断两边字符串大小,将字符串交换位置,交换后长度小的字符串就固定位置,
然后长度大的字符串重新划分左右字符,并按上的方法交换,
当左边字符长度等于右边字符长度,两边整体交换程序结束。

原字符串:abcdefg
第一次交换:(efgd)abc
第二次交换:(d)fge(abc)
第三次交换:(de)gf(abc)
第四次交换(左边字符串等于右边字符串):defgabc

与解法一对比,coding难很多,但是整体的比较次数要更少,适合交换代价很昂贵的一些场景

代码如下:

//解法二:
public static String change2(char[] str, int lSize){
    int L = 0;
    int R = str.length - 1;
    //左边字符串长度
    int lPart = lSize;
    //右边字符串长度
    int rPart = str.length - lPart;
    //左右字符串中较小字符串的长度
    int same = Math.min(lPart, rPart);
    //左边字符串与右边字符串长度差
    int diff = lPart - rPart;
    exchange(str, L, R, same);
    while(diff != 0){
        if (diff < 0){
            //左边字符串长度小于右边,此时交换完左边固定same长度字符
            R -= same;
            rPart = -diff;
        }else {
            //此时左边字符串大于右边,此时交换完右边固定same长度字符
            L += same;
            lPart = diff;
        }
        same = Math.min(lPart, rPart);
        //当diff=0时,说明左边的字符和右边的字符长度相同,此时只需要将左边字符和右边字符进行整体交换变完成
        //最坏情况就是当diff=0时,左边字符和右边字符长度都为1
        diff = lPart - rPart;
        exchange(str, L, R, same);
    }
    return new String(str);
}

//str[L...]数出size大小和str[...R]输出size大小出来进行交换
private static void exchange(char[] str, int L, int R, int size) {
    //确定右边字符开始交换的位置
    int i = R - size + 1;
    char temp = 0;
    while (size-- != 0){
        temp = str[L];
        str[L++] = str[i];
        str[i++] = temp;
    }
}

main测试代码

public static void main(String[] args) {
    String arr = "abcdefg";
    //String change = change(arr.toCharArray(), 3);
    String change = change2(arr.toCharArray(), 3);
    System.out.println(change);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值