算法训练DAY8 |力扣344.反转字符串&&力扣541.反转字符串II&&力扣剑指Offer 05.替换空格&&1力扣151.翻转字符串里的单词&&力扣剑指Offer58-II.左旋转字符串

344.反转字符串


原题链接:力扣344.反转字符串

题目描述


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

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

示例 1:

输入:s = ["h","e","l","l","o"]
输出:["o","l","l","e","h"]
示例 2:

输入:s = ["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]
 

提示:

1 <= s.length <= 105
s[i] 都是 ASCII 码表中的可打印字符

问题分析


  • 给定一个字符串,将字符串反向输出
  • 不能使用额外的空间,只能对原字符串直接进行操作;

解法思路


这道题可以使用双指针的思路,定义一个左右指针,分别指向字符数组的头和尾,然后将所指向的内容进行交换,左指针进1,右指针退1,直到左右指针相遇;

示例代码

c语言

void reverseString(char* s, int sSize){
    int left = 0;
    int right = sSize - 1;
    while(left <= right)
    {
        char temp = s[left];
        s[left] = s[right];
        s[right] = temp;
        left++;
        right--;
    }    
}

java

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

    }
}


541.反转字符串Ⅱ


原题链接:力扣541.反转字符串Ⅱ

题目描述


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

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

示例 1:

输入:s = "abcdefg", k = 2
输出:"bacdfeg"
示例 2:

输入:s = "abcd", k = 2
输出:"bacd"
 

提示:

1 <= s.length <= 104
s 仅由小写英文组成
1 <= k <= 104

问题分析


  • 给定一个字符串和一个整数值k,每2k个字符,反转前k个字符;
  • 若剩余字符少于k个,则全部反转;若在k到2k之间,则反转前k个字符;

解法思路


这道题用的反转的核心代码和上一题无异,可以用双指针的想法和思路来进行交换;只需要给外层加上循环,每2k进行一次操作,同时判断字符的个数,进行不同的赋值;

示例代码 


c语言

char * reverseStr(char * s, int k){
    int len = strlen(s);
    for(int i = 0; i < len; i += (2*k))
    {
        k = i + k > len ? len - i : k;
        int left = i;
        int right = i + k - 1;
        while(left < right)
        {
            char temp = s[left];
            s[left] = s[right];
            s[right] = temp;
            left++;
            right--;
        }
    }
    return s;
}

java

class Solution {
    public String reverseStr(String s, int k) {
        char []sh  = s.toCharArray();
        for(int i = 0; i < sh.length; i += 2 * k)
        {
            
            int left = i;
            int right = Math.min(sh.length-1,left + k - 1);
            while(left < right)
            {
                char temp = sh[left];
                sh[left] = sh[right];
                sh[right] = temp;
                left++;
                right--;
            }
        }
        return  new String(sh);
    }
}


力扣剑指Offer 05.替换空格


原题链接:剑指Offer 05.替换空格

题目描述


请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

示例 1:

输入:s = "We are happy."
输出:"We%20are%20happy."

问题分析


  • 将字符串中的空格替换为%20;

解法思路


函数

直接用Java中的库函数进行替换;

双指针法

将数组扩充到每个空格替换%20之后大小,然后从后往前替换空格,前指针指向旧长度,后指针指向新长度,两个指针同时向前移动,将前指针指向的内容赋给后指针,遇到空格,后指针指向的内容赋值为%20;

示例代码


c语言(双指针法)

char* replaceSpace(char* s){
    int count = 0;
    int len = strlen(s);
    for(int i = 0; i < len; i++) {
        if(s[i] == ' ')
        count++;
    }
    int newlen = len + count * 2;
    char *result = (char*)malloc(sizeof(char)*(newlen+1));
    for(int i = len - 1, j = newlen - 1; i >= 0; i--,j--) {
        if(s[i] != ' ')
        result[j] = s[i];
        else{
            result[j--] = '0';
            result[j--] = '2';
            result[j] = '%';
        }
    }
    result[newlen] = '\0';
    return result;
}

java(函数)

class Solution {
    public String replaceSpace(String s) {
        if(s == null)
        return null;
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < s.length(); i++) {
            if(s.charAt(i) == ' ')
            sb.append("%20");
            else
            sb.append(s.charAt(i));
        }
        return sb.toString();

    }
}


151.翻转字符串里的单词


原题链接:力扣151.翻转字符串里的单词

 题目描述


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

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

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

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

示例 1:

输入:s = "the sky is blue"
输出:"blue is sky the"
示例 2:

输入:s = "  hello world  "
输出:"world hello"
解释:反转后的字符串中不能存在前导空格和尾随空格。
示例 3:

输入:s = "a good   example"
输出:"example good a"
解释:如果两个单词间有多余的空格,反转后的字符串需要将单词间的空格减少到仅有一个。
 

提示:

1 <= s.length <= 104
s 包含英文大小写字母、数字和空格 ' '
s 中 至少存在一个 单词
 

进阶:如果字符串在你使用的编程语言中是一种可变数据类型,请尝试使用 O(1) 额外空间复杂度的 原地 解法

问题分析


  • 给定一个字符串,该字符串由若干个单词组成;
  • 字符串前或者尾以及单词中间可能有多个空格,只需单词之间间隔一个空格,头尾不需要空格;
  • 然后将所有的单词反转,然后进行输出;

解法思路


首先,将多余的空格去除,然后将全部字符串进行反转,最后将每一个单词进行反转;

示例代码


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

    private StringBuilder removeSpace(String s) {
        // System.out.println("ReverseWords.removeSpace() called with: s = [" + s + "]");
        int start = 0;
        int end = s.length() - 1;
        while (s.charAt(start) == ' ') start++;
        while (s.charAt(end) == ' ') end--;
        StringBuilder sb = new StringBuilder();
        while (start <= end) {
            char c = s.charAt(start);
            if (c != ' ' || sb.charAt(sb.length() - 1) != ' ') {
                sb.append(c);
            }
            start++;
        }
        // System.out.println("ReverseWords.removeSpace returned: sb = [" + sb + "]");
        return sb;
    }

    /**
     * 反转字符串指定区间[start, end]的字符
     */
    public 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 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;
        }
    }
}

 剑指Offer58-Ⅱ.左旋字符串


 原题链接:剑指Offer58-Ⅱ.左旋字符串

题目描述


 字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。

示例 1:

输入: s = "abcdefg", k = 2
输出: "cdefgab"
示例 2:

输入: s = "lrloseumgh", k = 6
输出: "umghlrlose"
 

限制:

1 <= k < s.length <= 10000

问题分析


  • 给定一个字符串和一个整数n,将该字符串的前n个顺序不变,移动到该字符串的末尾; 

解法思路


首先,反转该字符串的前n个元素,然后反转剩余的元素,最后将该字符串反转,进行输出就可以; 

示例代码


class Solution {
    public String reverseLeftWords(String s, int n) {
        StringBuilder sb = new StringBuilder(s);
        reverseString(sb,0,n-1);
        reverseString(sb,n,sb.length()-1);
        reverseString(sb,0,sb.length()-1);
        return sb.toString();

    }
    public void reverseString(StringBuilder sb,int left,int right) {
        while(left < right)
        {
            char temp = sb.charAt(left);
            sb.setCharAt(left,sb.charAt(right));
            sb.setCharAt(right,temp);
            left++;
            right--;

        }
    }
}

今日总结


首先,对双指针的应用又多了一个,双指针可以用来反转字符串,其次,清楚的直到c语言有很多不足之处,真的很不适合用来刷题,现成能用的库函数真的很少,刷题很不方便,5个题,核心都是反转字符串,对该操作有了很深刻的理解和认识;

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