LeetCode字符串算法题——Java题解与思路

1.最长公共前缀

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 ""

题解思路:

首先遍历数组,取到长度最短字符串作为比较基准。再次遍历数组对字符串元素进行与基准字符串等长截取,并比较字符串是否相同,如不相同截掉基准字符串的最后一个字符继续比较,直至取到公共前缀(空字符串)返回。

此题可采用暴力破解方式,但耗时更长,内存消耗更多。

public String longestCommonPrefix(String[] strs) {
        if (strs.length == 0) return "";
        String result = "";
        int minLength = Integer.MAX_VALUE;
        for (String str : strs) {
            if (str.length() < minLength) {
                minLength = str.length();
                result = str;
            }
        }
        for (String str : strs) {
            while (!str.substring(0, minLength).equals(result)) {
                result = result.substring(0, --minLength);
            }
        }
        return result;
}

2.最长回文子串

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

题解思路:

动态规划方式:

    /*
        动态规划方式:最长回文字符串
    */
    public static String longestPalindrome(String s) {
        // 特判
        if (s.length() == 0 || s.length() == 1) return s;
        int length = s.length();
        // 用来记录字符串长度内,任意两个索引范围内的字符是否是回文字符串
        boolean[][] em = new boolean[length][length];
        String result = "";
        for (int l = 0; l < length; l++) {// 循环截取不同长度字符串进行验证,l为j-i角标的差值
            for (int i = 0; i + l < length; i++) {// 截取的字符串验证两端(i,j)字符是否相同
                int j = i + l;
                if (l == 0) {// 截取的只有一个字符,最长回文就是当前一个字符
                    em[i][j] = true;
                } else if (l == 1) {// 截取只有两个字符,判断两个字符是否相同
                    em[i][j] = (s.charAt(i) == s.charAt(j));
                } else {// 截取字符数>2时,判断i j字符是否相等的同时,会取到之前判断过的i+1,j-1位置上的字符是否相同
                    em[i][j] = (s.charAt(i) == s.charAt(j) && em[i + 1][j - 1]);
                }
                // 当前两个索引范围的字符串是回文的,并且用result记录长度更长的一个
                if (em[i][j] && l + 1 > result.length()) {
                    result = s.substring(i, i + l + 1);
                }
            }
        }
        return result;
    }

3.翻转字符串里的单词

给定一个字符串,逐个翻转字符串中的每个单词。

题解思路:

调用splite()方法分割为String[],再倒叙拼接为字符串,并在拼接每个单词后拼接空格,最后trim一下。

    public String reverseWords(String s) {
        StringBuilder sb = new StringBuilder();
        String[] words = s.split(" ");
        for (int i = words.length - 1; i >= 0; i--) {
            sb.append(words[i]);
            if (words[i].length() > 0 && i != 0)
                sb.append(" ");
        }
        return sb.toString().trim();
    }

4.反转字符串(双指针方式)


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

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

你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。

题解思路:

利用双指针(两端反向)分别从头和尾循环进行元素互换,直到两个指针相遇或头大于尾指针。

    public void reverseString(char[] s) {
        for (int i = 0; i < (s.length + 1) / 2; i++) {
            int j = s.length - i - 1;
            char temp = s[i];
            s[i] = s[j];
            s[j] = temp;
        }
    }

5.反转字符串中的单词 III(双指针)

给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。

题解思路:

采用双指针解法,定义双指针(同向快慢)fast、slow,fast先指针向后遍历字符数组当遇到空格时,记录空格的下一位next并从空格的前一位与slow进行循环互换元素。互换完毕后将slow与fast同时指向所记录的next的位置上,fast继续向后遍历与反转调换。

    public String reverseWords(String s) {
        char[] chars = s.toCharArray();
        int fast = 0, slow = 0;
        int length = chars.length;
        while (fast < length) {
            while (fast < length && chars[fast] != ' ') {
                fast++;
            }
            // 记录下一个单词开始字符角标
            int next = fast + 1;
            fast--;
            // 循环翻转单词字符串
            while (fast > slow) {
                // 互换两者位置
                char temp = chars[slow];
                chars[slow] = chars[fast];
                chars[fast] = temp;
                fast--;
                slow++;
            }
            fast = next;
            slow = next;

        }
        return new String(chars);
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值