leetcode题解-344. Reverse String && 541. Reverse String II && 345. Reverse Vowels of a String

来源:互联网 发布:淘宝素材图片 编辑:程序博客网 时间:2024/05/16 10:25

今天的三道都是字符串反转的题目,也相对比较简单,我们先来看第一道题目:

Write a function that takes a string as input and returns the string reversed.Example:Given s = "hello", return "olleh".

本题没什么好说的就是一个最简单的字符串反转问题,可以自己写程序使用两个指针也可以调用内置函数,两种方法代码如下所示:

    //内置函数    public String reverseString(String s) {        StringBuilder res = new StringBuilder(s);        return res.reverse().toString();    }    //双指针法    public String reverseString1(String s) {        char[] word = s.toCharArray();        int i = 0;        int j = s.length() - 1;        while (i < j) {            char temp = word[i];            word[i] = word[j];            word[j] = temp;            i++;            j--;        }        return new String(word);    }

541、 Reverse String II题目:

Given a string and an integer k, you need to reverse the first k characters for every 2k characters counting from the start of the string. If there are less than k characters left, reverse all of them. If there are less than 2k but greater than or equal to k characters, then reverse the first k characters and left the other as original.Example:Input: s = "abcdefg", k = 2Output: "bacdfeg"Restrictions:The string consists of lower English letters only.Length of the given string and k will in the range [1, 10000]

本题是将字符串中的每2k个字符的前k个进行反转,后k个保持不变,如果最后剩下的不足k个则全部翻转,大于等于k个则将前k个反转。可以使用上面的双指针法来解决此题,先看我的解法:

    //35%    public static String reverseStr(String s, int k) {        char [] res = s.toCharArray();        int n = s.length()/(2*k), i;        //取前面2k*n个进行反转        for(i=0; i<n; i++){            int left=i*2*k, right=left+k-1;            while(left < right){                char tmp = res[left];                res[left] = res[right];                res[right] = tmp;                left ++;                right --;            }        }        //对最后剩余的进行反转,right设置为k和剩余字符串的较小值        int left=i*2*k, right=Math.min(left+k-1, s.length()-1);        while(left < right){            char tmp = res[left];            res[left] = res[right];            res[right] = tmp;            left ++;            right --;        }        return new String(res);    }

其实仔细一想上面的代码是可以进行简化的,可以把后面的判断语句也融合到前面的循环当中,

    //44%    public String reverseStr1(String s, int k) {        char[] arr = s.toCharArray();        int n = arr.length;        int i = 0;        while(i < n) {            int j = Math.min(i + k - 1, n - 1);            swap(arr, i, j);            i += 2 * k;        }        return String.valueOf(arr);    }    private void swap(char[] arr, int l, int r) {        while (l < r) {            char temp = arr[l];            arr[l++] = arr[r];            arr[r--] = temp;        }    }

然后在理清反转关系之后我们还可以使用StringBuilder内置的insert函数进行简化反转操作:

    //68%    public String reverseStr2(String s, int k) {        StringBuilder res = new StringBuilder();        for (int i = 0; i < s.length(); i++) {            if (i % (2 * k) < k) res.insert(i - i % (2 * k), s.charAt(i));            else res.append(s.charAt(i));        }        return res.toString();    }

接下来看最后一道题目:

Write a function that takes a string as input and reverse only the vowels of a string.Example 1:Given s = "hello", return "holle".Example 2:Given s = "leetcode", return "leotcede".Note:The vowels does not include the letter "y".

只反转字符串中的元音“aeiouAEIOU”,有下面三种方法,思路是一样的,都是双指针法,从两侧找元音然后翻转,只是判断元音的数据结构不同,代码的效率也有很大差异,从中我们可以得到下面的结论:
字符串的contains函数效率没有Set效率高,但是这种数据结构的效率都远低于switch语句来的简单方便

    //18%,使用字符串存储元音,然后使用contains函数判断    public String reverseVowels(String s) {        if(s == null || s.length()==0) return s;        String vowels = "aeiouAEIOU";        char[] chars = s.toCharArray();        int start = 0;        int end = s.length()-1;        while(start<end){            while(start<end && !vowels.contains(chars[start]+"")){                start++;            }            while(start<end && !vowels.contains(chars[end]+"")){                end--;            }            char temp = chars[start];            chars[start] = chars[end];            chars[end] = temp;            start++;            end--;        }        return new String(chars);    }    //55%,使用set存储元音,然后使用contains()函数判断    public String reverseVowels1(String s) {        char[] list=s.toCharArray();        Set<Character> set=new HashSet<>();        set.add('a');        set.add('e');        set.add('i');        set.add('o');        set.add('u');        set.add('A');        set.add('E');        set.add('I');        set.add('O');        set.add('U');        for (int i=0, j=list.length-1; i<j; ) {            if (!set.contains(list[i])) {                i++;                continue;            }            if (!set.contains(list[j])) {                j--;                continue;            }            char temp=list[i];            list[i]=list[j];            list[j]=temp;            i++;            j--;        }        return String.valueOf(list);    }    public static boolean isVowel(char a){        switch(a){            case ('a') : return true;            case ('e') : return true;            case ('i') : return true;            case ('o') : return true;            case ('u') : return true;            case ('A') : return true;            case ('E') : return true;            case ('I') : return true;            case ('O') : return true;            case ('U') : return true;            default : return false;        }    }    //99%,直接使用switch语句判断是否为元音    public static String reverseVowels2(String s) {        if (s.length()<2) return s;        char[] tab = s.toCharArray();        int j = tab.length - 1;        int i = 0;        while( i < j ) {            if (!isVowel(tab[i]))                i++;            else {                while (j!=i && !isVowel(tab[j]))                    j--;                char temp = tab[i];                tab[i] = tab[j];                tab[j] = temp;                i++;                j--;            }        }        return new String(tab);    }
阅读全文
0 0
原创粉丝点击