自学内容网 自学内容网

【算法系列-字符串】反转字符串中的单词

【算法系列-字符串】反转字符串中的单词

1. 算法分析

【题目链接】151. 反转字符串中的单词 - 力扣(LeetCode)

这道题比较麻烦的是需要去除多余的空格并保留单词间的空格,我这里提供一份使用库函数(java中的split)解决的代码:

class Solution {
    public String reverseWords(String s) {
        String[] arr = s.split(" ");
        reverse(arr, 0, arr.length - 1);
        StringBuffer sub = new StringBuffer();
        for (int i = 0;i < arr.length;i++) {
            if ("".equals(arr[i])) {
                continue;
            }
            sub.append(arr[i]);
            sub.append(" ");
        }
        if (sub.substring(sub.length() - 1).equals(" ")) {
            return sub.substring(0, sub.length() -1).toString();
        }
        return sub.toString();
    }

    public void reverse(String[] arr, int left, int right) {
        while (left < right) {
            String temp = arr[left];
            arr[left++] = arr[right];
            arr[right--] = temp;
        }
    }
}

但这样做空间复杂度就会比较高,为了起到锻炼作用,我这里也用另一种方式解决这道题,那就是双指针!

分三步走:

  1. 去除多余空格
  2. 反转整个字符串
  3. 对每个单词进行反转

2. 解题过程

2.1 去除多余空格

使用快慢指针的方式来删除多余的空格,具体方式与之前写过的一篇文章类似,不理解的可以参考一下: 【算法系列-移除元素】

需要注意:

  • 当fast指向了一个新的单词,且当slow指向位置不是数组首位时,需要在这个新单词前面加一个空格;
  • 每一次都要将新单词的所有字符都遍历完毕才能结束循环;

代码如下:

public char[] removeSpace(char[] arr) {
   int slow = 0;
   for (int fast = 0;fast < arr.length;fast+
       if (arr[fast] != ' ') {
           
           // 进入这里表示fast指向了一个新的单词,且当slow指向位置不是数组首位时,需要在这个新单词前面加一个空格
           if (slow !=  0) {
               arr[slow++] = ' ';
        
           // 需要循环将这个单词遍历完
           while (fast < arr.length && arr[fast] != ' ') {
               arr[slow++] = arr[fast++];
           }
       }
   }
   char[] retArr = new char[slow];
   System.arraycopy(arr, 0, retArr, 0, slow);
   return retArr;
}

2.2 反转整个字符串

这一个方法与上篇文章【算法系列-反转字符串】介绍的一样,这里就不过多赘述

代码如下:

public void reverse(char[] arr, int left, int right
    while (left < right) {
        char temp = arr[left];
        arr[left++] = arr[right];
        arr[right--] = temp;
    }
} 

2.3 对每个单词进行反转

需要注意:

  • fast == arr.length 是为了判断指向最后一个单词时的情况;
  • 当fast指向数组末尾 或 fast指向的字符为空时,对这个单词进行反转(slow 到 fast - 1 便是当前单词的范围);
  • slow = fast + 1 这里的 + 1 是为了跳过空字符;

代码如下:

public void reverseWord(char[] arr
    int slow = 0;
    for (int fast = 0;fast <= arr.length;fast++) {
        if (fast == arr.length || arr[fast] == ' ') {
            // fast == arr.length 是为了判断指向最后一个单词时的情况
            // 当fast指向数组末尾 或 fast指向的字符为空时,对这个单词进行反转(slow 到 fast - 1 便是当前单词的范围)
            reverse(arr, slow, fast - 1);
            slow = fast + 1; // +1 是为了跳过空字符
        }
    }
}

3. 代码示例

总的代码如下:

class Solution {
    public String reverseWords(String s) {
        char[] arr = s.toCharArray();

        // 1. 去除多余空格
        arr = removeSpace(arr);

        // 2. 反转所有字符
        reverse(arr, 0, arr.length - 1);

        // 3. 对每个单词进行反转
        reverseWord(arr);

        return new String(arr);

    }

    public char[] removeSpace(char[] arr) {
        int slow = 0;
        for (int fast = 0;fast < arr.length;fast++) {

            if (arr[fast] != ' ') {
                
                // 进入这里表示fast指向了一个新的单词,且当slow指向位置不是数组首位时,需要在这个新单词前面加一个空格
                if (slow !=  0) {
                    arr[slow++] = ' ';
                }

                // 需要循环将这个单词遍历完
                while (fast < arr.length && arr[fast] != ' ') {
                    arr[slow++] = arr[fast++];
                }
            }
        }
        char[] retArr = new char[slow];
        System.arraycopy(arr, 0, retArr, 0, slow);
        return retArr;
    }

    public void reverse(char[] arr, int left, int right) {

        while (left < right) {
            char temp = arr[left];
            arr[left++] = arr[right];
            arr[right--] = temp;
        }
    } 

    public void reverseWord(char[] arr) {

        int slow = 0;
        for (int fast = 0;fast <= arr.length;fast++) {
            if (fast == arr.length || arr[fast] == ' ') {
                // fast == arr.length 是为了判断指向最后一个单词时的情况
                // 当fast指向数组末尾 或 fast指向的字符为空时,对这个单词进行反转(slow 到 fast - 1 便是当前单词的范围)
                reverse(arr, slow, fast - 1);
                slow = fast + 1; // +1 是为了跳过空字符
            }
        }
    }
}

以上便是对反转字符串中的单词问题的介绍了!!后续还会继续分享其它算法系列内容,如果这些内容对大家有帮助的话请给一个三连关注吧💕( •̀ ω •́ )✧( •̀ ω •́ )✧✨


原文地址:https://blog.csdn.net/Mwt258/article/details/142914683

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!