Day8|字符串

题目

反转字符串
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

public void reverseString(char[] s) {
        for(int i=0;i<s.length/2;i++){
            char temp=s[i];
            s[i]=s[s.length-1-i];
            s[s.length-1-i]=temp;
        }
    }

该题的交换两个元素还有另外一种写法:

s[i] ^= s[j];
s[j] ^= s[i];
s[i] ^= s[j];

通过位运算的方式

541. 反转字符串 II

给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。

如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。

首先写一个反转字符串的函数reverse(String s,int k)

public static String reverse(String s,int k){
        StringBuilder sb=new StringBuilder();
        for(int i=s.length()-1;i>=0;i--){
            sb.append(s.charAt(i));
        }

        return sb.toString();

    }

此时目的是将传来的参数s全部按照s的长度进行反转,由于string类型不可修改,因此重新返回一个string类型的对象。
此时完成函数的主体部分,使用递归的方式来计算反转字符串,先判断字符串长度,大于2k则先将前k进行翻转,k-2k保持原状,2k后面的再调用该函数

 public static  String reverseStr(String s, int k) {
        int size=s.length();
        if(size<k){
            return reverse(s,k);
        }else if(size>=k&&size<2*k){
            return reverse(s.substring(0,k),k)+s.substring(k);
        }else return reverse(s.substring(0,k),k)+s.substring(k,2*k)+reverseStr(s.substring(2*k),k);

    }

替换空格
请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
这题最简单的实现方式就是使用库函数调用replaceAll的方式进行
但是要做到极致就尽量少使用额外的空间,可以使用双指针法,第一个指针指向重新定向长度的数组,第二个指针指向原指针的末尾,从后往前进行执行。

 // return s.replaceAll(" ","%20");
        if(s==null||s.length()==0)return s;
        StringBuilder sb=new StringBuilder();
        for(int i=0;i<s.length();i++){
            if(s.charAt(i)==' '){
                sb.append("   ");
            }
        }
        if(sb.length()==0){
            return s;//说明没有空格
        }
        int left=s.length()-1;
        s+=sb.toString();
        char[] str=s.toCharArray();
        int right=s.length()-1;
        while(left>=0){
            if(s.charAt(left)==' '){
                str[right--]='0';
                str[right--]='2';
                str[right]='%';
                
            }else{
                str[right]=s.charAt(left);
            }
            right--;
            left--;
        }
        return new String(str);
    }

151. 反转字符串中的单词
给你一个字符串 s ,请你反转字符串中 单词 的顺序。

单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。

返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。

注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。

  • 我的思路是使用双指针的方式,从后往前遍历,然后分以下情形,如果left是" ",此时判断是不是left==right,如果是,说明中间不存在字符串,然后直接left++;right++;如果并不是相等,就说明中间存在一个word,此时找到word的首尾范围,substring(left+1,right+1),一旦left不是“ ”,又存在两种情形,一种是left是0,说明已经形成了一个word,如果不是,那么left–。
public String reverseWords(String s) {
int left=s.length()-1;int right=s.length()-1;
        StringBuilder sb=new StringBuilder();
        
        while(left>=0){
            if(s.charAt(left)!=' '){
                if(left==0){
                    if(sb.length()!=0){
                        sb.append(" ");
                    }
                    sb.append(s.substring(left,right+1));
                }left--;
            }else{
                if(left==right){
                    left--;
                    right--;
                }else{
                    String m=s.substring(left+1,right+1);
                    if(sb.length()!=0){
                        sb.append(" ");
                    }
                    sb.append(m);
                    
                    left--;
                    right=left;
                }
            }
            
        }
           
       
       return sb.toString();

时间复杂度为O(n);
而同时提高难度,如果空间复杂度控制在O(1),那么就不能有额外的空间,只能进行原地操作。思路为,先将字符串中的多余空格删除,再将字符串翻转,再将其中的单词翻转,就能形成正确的答案。

剑指 Offer 58 - II. 左旋转字符串
给你一个字符串 s ,请你反转字符串中 单词 的顺序。

单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。

返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。

注意:输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。
这道题目也非常类似,依然可以通过局部反转+整体反转 达到左旋转的目的。

具体步骤为:

反转区间为前n的子串
反转区间为n到末尾的子串
反转整个字符串

 public String reverseLeftWords(String s, int n) {
        StringBuilder sb=new StringBuilder();
        for(int i=0;i<s.length();i++){
            int count=(i+2)%s.length();
            sb.append(s.charAt(count));
        }
        return sb.toString();
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值