day8 反转字符串 、 541、反转字符串II卡码网:54.替换数字

leetcode:344反转字符串

344. 反转字符串 - 力扣(LeetCode)

  • 这道题目就是用双指针的方式,进行收尾交换,更新2个指针,向中间靠拢进行再次的更换。 
  • 注意我们的temp一定是char字符串类型,不是int类型;
  • 方法是void,所以没有返回值。
  • 代码如下:
  •  
    • class Solution {
          public void reverseString(char[] s) {
              // 双指针方法进行头尾的22交换
              char temp = 0;
              int before = 0;
              int after = s.length - 1;
      
              while (before < after) {
                  temp = s[before];
                  s[before] = s[after];
                  s[after] = temp;
                  before++;
                  after--;
              }
      
          }
      }
后期还是转python吧
class Solution(object):
    def reverseString(self, s):
        """
        :type s: List[str]
        :rtype: None Do not return anything, modify s in-place instead.
        """
        left,right =0,len(s)-1
        for i in range (len(s)//2):
            s[left],s[right] =s[right],s[left]
            left +=1
            right -=1

541. 反转字符串II

541. 反转字符串 II - 力扣(LeetCode)

用一行代码就能把分类问题一起总结:

int end = Math.min(i + k - 1, s.length() - 1); // 反转前 k 个字符

用一个end把各种情况都考虑

第一种情况就是 ,前面的每个2k阶段,都是用这个start和end能约束

第二种情况:剩下的部分大于k,小于2k, 还是按照 end =i+k-1的逻辑,和第一种情况一样进行转换字符串

最后一种情况就是: 剩下的不足k,按照起点算起,到end=s.length() - 1的这部分, 这样把题目的几种分类问题都一起处理了。

class Solution {
    public String reverseStr(String s, int k) {
        char[] chars = s.toCharArray();  // 将字符串转换成字符数组

        // 每 2k 个字符为一个段落
        for (int i = 0; i < s.length(); i += 2 * k) {
            // 计算反转区间的结束位置
            int start = i;
            int end = Math.min(i + k - 1, s.length() - 1); // 反转前 k 个字符

            // 反转前 k 个字符
            while (start < end) {
                char temp = chars[start];
                chars[start] = chars[end];
                chars[end] = temp;
                start++;
                end--;
            }
        }

        // 将字符数组转换回字符串并返回
        return new String(chars);
    }
}

用python写

class Solution(object):
    def reverseStr(self, s, k):
        """
        :type s: str
        :type k: int
        :rtype: str
        """
        chars =list(s)
        n=len(chars)
        for i in range(0,n,2*k):
            left,right =i,min(i+k-1,n-1)
            while left <right:
                chars[left],chars[right]=chars[right],chars[left]
                left +=1
                right -=1
        return ''.join(chars)

示例分析:"abcdefg", k=2

  1. 初始状态"abcdefg"
    • 将字符串分为两组:"abcd" (第一个2k组) 和 "efg" (剩余字符)
  2. 第一步:反转第一个2k组的前k个字符
    • 反转"ab""ba"
    • 结果:"bacdefg"
  3. 第二步:反转第二个区间的前k个字符
    • 剩余部分"efg",前k个字符是"ef"
    • 反转"ef""fe"
    • 结果:"bacdfeg"
  4. 最终结果"bacdfeg"

边界情况分析

  1. 剩余字符少于k个
    • 例如:"ab", k=3
    • 通过min(i+k-1, n-1)自动处理为全部反转
  2. k < 剩余字符 < 2k
    • 例如:"abcde", k=2
    • 只反转前k个字符,其余保持不变
  3. 空字符串
    • 无需特殊处理,直接返回空字符串

算法复杂度

  • 时间复杂度:O(n),每个字符最多被处理一次
  • 空间复杂度:O(n),需要一个与原字符串等长的字符数组

这种算法的巧妙之处在于通过计算边界条件和步长,简洁地处理了所有可能的情况,而不需要繁琐的条件判断。

54. 替换数字(第八期模拟笔试)

54. 替换数字(第八期模拟笔试)

这个题目解题思路是: 先计算旧字符串中有多少个数字,然后我们创建新的字符数组时候,便于定义新数组的大小。  我们在原来的字符串长度s.length() 的基础上,再进行扩充每个数字的5倍,进行加和。 之所以是5倍,是因为number这6个空间中,有一个位置最后会被原来的数字空位填充,所以是5而不是6.  并且我们使用System.arraycopy() 的方式,把旧数组的(字符串转数组s.toCharArray(), 方便后续的数组拷贝)拷贝到新数组的开头。 然后用i和j 两个指针, i指针指向新数组的末尾, j指向拷贝来的数组的尾字符位置。 如果是字母, 新数组的末尾进行替换填充,如果是数字,就给6个空间,一次向前填充number。  最后 使用new String(新数组) 返回一个String类型的数据。

当然在acm格式条件下,我们需要创建输入的的类 Scanner scanner =new Scanner (System.in),以及使用scanner实例中的方法scanner.next() ,获取对应的字符串 并最后关闭scanner实例的流式使用。 代码中的确需要在使用完 Scanner 后关闭它,以确保流被正确释放

代码如下:
 

import java.util.Scanner;

public class Main  {
    /* code */
    public static  void main (String[] args){
        Scanner scanner  = new Scanner(System.in);
        String s = scanner.next();
        System.out.println(replaceNumber(s));
        scanner.close();
    }
    public static String replaceNumber(String s){
        int count=0;
        for(int i=0;i<s.length();i++){
            if(Character.isDigit(s.charAt(i))){
                count ++;
            }
        }
        char [] newStr = new char [s.length()+count*5];
        System.arraycopy(s.toCharArray(),0,newStr,0,s.length());
        //从后段进行判断并进行填充:
        for(int i=newStr.length-1, j=s.length()-1;j<i;i-- ,j--){
            if(! Character.isDigit( newStr[j])){
                newStr[i]=newStr[j];
            }else{
                newStr[i]='r';
                newStr[i-1]='e';
                newStr[i-2]='b';
                newStr[i-3]='m';
                newStr[i-4]='u';
                newStr[i-5]='n';
                i -=5;
            }
        }
        return new String(newStr);
        
    }
    
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值