day08算法打卡|字符串01|Leetcode344:反转字符串、541:反转字符串II、字符串数字替换、151翻转字符串、右旋字符串|主要使用数组那部分的双指针思路解题

Leetcode344:反转字符串

题目链接:https://leetcode.cn/problems/reverse-string/description/

题目分析: 双指针实现原地反转 

Java实现代码1:引入temp交换

class Solution {
    public void reverseString(char[] s) {
        int left = 0;
        int right = s.length-1;
        while(left

Java实现代码2:位运算实现交换

class Solution {
    public void reverseString(char[] s) {
        int left = 0;
        int right = s.length-1;
        while(left

tips:解析位运算不借助其他元素,交换两个变量值

day08算法打卡|字符串01|Leetcode344:反转字符串、541:反转字符串II、字符串数字替换、151翻转字符串、右旋字符串|主要使用数组那部分的双指针思路解题_第1张图片


Leetcode541:反转字符串II

题目链接:https://leetcode.cn/problems/reverse-string-ii/

分析:字符串翻转的基础上增加一些规则;

Java实现代码1:对字符数组修改

将字符串转化为字符数组,结合上一题函数并结合翻转规则实现

  • 将for循环的++条件修改为增加2k,思路打开,
  • 结合字符串反转函数将问题简单化,
  • 主要考虑关于k,2k等边界值的处理
  • tips:
    • 字符串-》字符数组 s.toCharArray()   
    • 字符数组-》字符串 new String(chararray);
class Solution {
    public String reverseStr(String s, int k) {
        char[] str = s.toCharArray();
        for(int i = 0 ;i

Java实现代码2:使用StringBuffer按规则翻转或不变后添加

class Solution {
    public String reverseStr(String s, int k) {
        int length = s.length();
        StringBuffer res = new StringBuffer();
        int start = 0;
        int indexK = 0; 
        int index2K = 0;
        while(startlength){
                indexK = length;
            }else{
                indexK = start+k;
            }
            //index2K赋值
            if(start+2*k >length){
                index2K = length;
            }else{
                index2K = start+2*k;
            }
            //添加翻转部分
            sb.append(s.substring(start,indexK)).reverse();
            res.append(sb);
            if(indexK

题:字符串数字替换

给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。 例如,对于输入字符串 "a1b2c3",函数应该将其转换为 "anumberbnumbercnumber"。


import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String str = in.nextLine();
        String resultstr = numberexchange(str);
        System.out.println(resultstr);
    }
    private static String numberexchange(String str){
        StringBuilder sb = new StringBuilder();
        int L= str.length();
        int star = 0;
        while(true){
            while((star=0)&&(str.charAt(star)-'z'<=0)){
                sb.append(str.charAt(star));
                star++;
            }
            while((star=0)&&(str.charAt(star)-'9'<=0)){
                sb.append("number");
                star++;
            }
            if (star>=L){
                break;
            }
        }
        return sb.toString();
    }
}

题目中心思想是要不额外申请空间,实现替换,但是java字符串无法修改,所以这么做没有有意义;其他语言可以用双指针实现


Leetcode151.翻转字符串

分析:此题比较复杂,大致分为三步解决问题

        eg:_ _ _ h i h i _ _ x _ jh _o o _

  1. 去除字符串多余的空格-》h i h i _  x _ j h _o o
  2. 整体反转-》o o _ h j _ x _ i h i h 
  3. 词汇反转-》o o _ j h _ x _ h i h i 

以上三个步骤里面主要第一步去除空格复杂一点,此题如果要求空间复杂度为O(1),那么java可能无法实现,因为其字符串是不可变得,但是也可以使用其双指针思路尝试实现;

具体step1 实现有两个方案,下面单列出此部分实现的方法函数:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;

public class Main {
    public static void main(String[] args) {
        String s1 = "  the  sky  is   blue  ";
        System.out.println("s原字符串|"+s1);
        System.out.println("法1去除空格|"+removeSpace1(s1).toString());
        String s2 = "  the  sky  is   blue  ";

        System.out.print("s原字符串|");
        char[] chars2 = s2.toCharArray();
        for (int i = 0; i < chars2.length; i++) {
            System.out.print(chars2[i]);
        }
        System.out.println("");
        System.out.print("法2去除空格|");
        char[] removespacechar = removeSpace2(chars2);
        for (int i = 0; i < removespacechar.length; i++) {
            System.out.print(removespacechar[i]);
        }
        System.out.println("");
    }
    private static StringBuilder removeSpace1(String s) {
        //使用两个指针移动找到去头尾空格的起始及终点位置
        int start = 0;
        int end = s.length()-1;
        while(s.charAt(start)==' '){
            start++;
        }
        while(s.charAt(end)==' '){
            end--;
        }
        //开启中间词汇及空格处理
        StringBuilder newremovespace = new StringBuilder();
        while(start<=end){
            //start指向位置不为空加进去 或 即使为空但是加去的最后一个字符不为空(== 在每个单词后补一个空格)
            if((s.charAt(start)!=' ')||(newremovespace.charAt(newremovespace.length()-1) != ' ')){
                char addLetter = s.charAt(start);
                newremovespace.append(addLetter);
            }
            start++;
        }
        return newremovespace;

    }
    private static char[] removeSpace2(char[] s){
        int slow = 0;
        for (int fast = 0; fast < s.length; fast++) {
            if(s[fast] != ' '){
                //如果不是首个词汇 就在每个词汇前加一个 space
                if(slow != 0){
                    s[slow] = ' ';
                    slow++;
                }
                //进入词汇的循环  fast 指向空格时退出循环
                //fast

day08算法打卡|字符串01|Leetcode344:反转字符串、541:反转字符串II、字符串数字替换、151翻转字符串、右旋字符串|主要使用数组那部分的双指针思路解题_第2张图片

整体实现:

Java解法1

class Solution {
    public String reverseWords(String s) {
        // System.out.println("ReverseWords.reverseWords2() called with: s = [" + s + "]");
        // 1.去除首尾以及中间多余空格
        StringBuilder sb = removeSpace1(s);
        // 2.反转整个字符串
        reverseString(sb, 0, sb.length() - 1);
        // 3.反转各个单词
        reverseEachWord(sb);
        return sb.toString();
    }
    public static void reverseString(StringBuilder sb, int start, int end) {
        // System.out.println("ReverseWords.reverseString() called with: sb = [" + sb + "], start = [" + start + "], end = [" + end + "]");
        while (start < end) {
            char temp = sb.charAt(start);
            sb.setCharAt(start, sb.charAt(end));
            sb.setCharAt(end, temp);
            start++;
            end--;
        }
        // System.out.println("ReverseWords.reverseString returned: sb = [" + sb + "]");
    }

    private static void reverseEachWord(StringBuilder sb) {
        int start = 0;
        int end = 1;
        int n = sb.length();
        while (start < n) {
            while (end < n && sb.charAt(end) != ' ') {
                end++;
            }
            reverseString(sb, start, end - 1);
            start = end + 1;
            end = start + 1;
        }
    }
    private static StringBuilder removeSpace1(String s) {
        //使用两个指针移动找到去头尾空格的起始及终点位置
        int start = 0;
        int end = s.length()-1;
        while(s.charAt(start)==' '){
            start++;
        }
        while(s.charAt(end)==' '){
            end--;
        }
        //开启中间词汇及空格处理
        StringBuilder newremovespace = new StringBuilder();
        while(start<=end){
            //start指向位置不为空加进去 或 即使为空但是加去的最后一个字符不为空(== 在每个单词后补一个空格)
            if((s.charAt(start)!=' ')||(newremovespace.charAt(newremovespace.length()-1) != ' ')){
                char addLetter = s.charAt(start);
                newremovespace.append(addLetter);
            }
            start++;
        }
        return newremovespace;

    }
}

Java解法2

class Solution {
public String reverseWords(String s) {
        char[] chars = s.toCharArray();
        //1.去除首尾以及中间多余空格
        chars = removeSpace2(chars);
        //2.整个字符串反转
        reverse(chars, 0, chars.length - 1);
        //3.单词反转
        reverseEachWord(chars);
        return new String(chars);
    }
    private static char[] removeSpace2(char[] s){
        int slow = 0;
        for (int fast = 0; fast < s.length; fast++) {
            if(s[fast] != ' '){
                //如果不是首个词汇 就在每个词汇前加一个 space
                if(slow != 0){
                    s[slow] = ' ';
                    slow++;
                }
                //进入词汇的循环  fast 指向空格时退出循环
                //fast= chars.length) {
            System.out.println("set a wrong right");
            return;
        }
        while (left < right) {
            chars[left] ^= chars[right];
            chars[right] ^= chars[left];
            chars[left] ^= chars[right];
            left++;
            right--;
        }
    }

    //3.单词反转
    public void reverseEachWord(char[] chars) {
        int start = 0;
        //end <= s.length() 这里的 = ,是为了让 end 永远指向单词末尾后一个位置,这样 reverse 的实参更好设置
        for (int end = 0; end <= chars.length; end++) {
            // end 每次到单词末尾后的空格或串尾,开始反转单词
            if (end == chars.length || chars[end] == ' ') {
                reverse(chars, start, end - 1);
                start = end + 1;
            }
        }
    }
}

day08算法打卡|字符串01|Leetcode344:反转字符串、541:反转字符串II、字符串数字替换、151翻转字符串、右旋字符串|主要使用数组那部分的双指针思路解题_第3张图片

day08算法打卡|字符串01|Leetcode344:反转字符串、541:反转字符串II、字符串数字替换、151翻转字符串、右旋字符串|主要使用数组那部分的双指针思路解题_第4张图片

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Scanner;
public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int index = sc.nextInt();
        String str = sc.next();
        char[] strArray = str.toCharArray();
        reverse(strArray,0,strArray.length-1);
        reverse(strArray,0,index-1);
        reverse(strArray,index,strArray.length-1);
        String s =String.valueOf(strArray);
        System.out.print(s);
    }
    private static void reverse(char[] str,int left,int right){
        int l = left;
        int r = right;
        while(l

你可能感兴趣的:(算法,java,leetcode)