【LeetCode-面试经典150题-day6】

14.最长公共前缀

题意:

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

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

【输入样例】

strs = ["flower","flow","flight"]

【输出样例】

"fl"

解题思路:

横向扫描,依次遍历字符串数组中的每个字符串,对于每个遍历到的字符串,更新最长公共前缀,当遍历完所有的字符串后,即可得到字符数组中的最长公共前缀;

class Solution {
    public String longestCommonPrefix(String[] strs) {
        if(strs == null || strs.length == 0){
            return "";
        }
        String strPre = strs[0];
        int count = strs.length;
        for(int i=1;i

时间: 击败了100.00%

内存: 击败了97.06%

解题思路:

二分查找,最长公共前缀的长度不会超过字符串数组中的最短字符串的长度。用minLength表示字符串数组中的最短字符串的长度,则可以在[0,minLength]的范围内通过二分查找得到最长公共前缀的长度。

class Solution {
    public String longestCommonPrefix(String[] strs) {
        if(strs == null || strs.length == 0){
            return "";
        }
        int minLength = Integer.MAX_VALUE;
        for(String str:strs){
            minLength = Math.min(minLength,str.length());
        }
        int low = 0,high = minLength;
        while(low < high){
            int mid = (high - low + 1)/2 +low;
            if(longPre(strs,mid)){
                low = mid;
            }else{
                high = mid - 1;
            }
        }
        return strs[0].substring(0,low);
    }
    private boolean longPre(String[] strs,int length){
         String str0 = strs[0].substring(0,length);
         int count = strs.length;
         for(int i=1;i

 时间: 击败了68.45%

内存: 击败了33.22%

 151.反转字符串中的单词

题意:

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

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

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

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

【输入样例】

s="the sky is blue "

【输出样例】

"blue is sky the"

解题思路:

1.遍历枚举,从字符串的最后一位开始遍历;

2.找到第一个非空字符,开始记录,当前索引end=i为找到单词的最后一位;

3. 继续遍历,直到找到下一个空格,当前索引start = ++i为找到的单词的上一位;

4.将单词截取,添加到新字符串中,注意单词后面要加一个空格;

5.遍历结束后,因为每个单词后面都加了一个空格,所以要把最后一位单词后的空格删了。

class Solution {
    public String reverseWords(String s) {
        StringBuffer str = new StringBuffer();
        int start,end;//每个单词的开始和结束索引

        for (int i = s.length() - 1; i >= 0; --i) {
            //当遍历到不是空格的时候,开始记录单词
            if(s.charAt(i) == ' '){
                //不做任何处理,继续遍历下一位
                continue;
            }
            //走到这一步,证明找到了不是空格的字符
            end = i;
            //继续遍历,找到下一个空格,证明找到了一个单词
            while(i>=0 && s.charAt(i) != ' '){
                --i;//不是空格且索引没越界,继续遍历
            }
            //跳出上述的while循环,证明i<0或者找到了空格了,把单词的开始索引记录一下
            start = ++i;//因为while里执行了--i,这里要加上
            str.append(s.substring(start,end+1)+" ");//每个单词后面有一个空格
        }
        //遍历结束了,要删掉最后一个单词后面的空格
        str.deleteCharAt(str.length()-1);
        return str.toString();
    }
}

 时间:击败了81.92%

内存:击败了44.08%

 6.N形变换

题意:

将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:

P   A   H   N
A P L S I I G
Y   I   R

之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"

【输入样例】

s="PAYPALISHIRING",numRows =3

【输出样例】

"PAHNAPLSIIGYIR"

解题思路:

想用压缩二维矩阵解决,先打个地基,直接用二维矩阵实现,其实二维矩阵最难的就是根据numRows的值判断每一列填入的行号,因为每一列都有数,但是除了0,n-1,(n-1)*2等列数是全部填满(字符足够的情况下),其余是斜着填充的。

1. 当numRows=1时,只有一行,直接return;当numRows>=s.length()时,字符串只填入第一列,读取结果也一样,直接return;

2. 在矩阵上写字符,先向下写numRows个,然后向右上继续填写numRows-2个字符(占numRows-2列),-2是因为第一行和最后一行都不写入,因此,Z字形变换的周期T=numRows+numRows-2=2numRows-2,每个周期占用1+numRows-2=numRows-1列。

3. 共有s.length()/T个周期,向上取整,矩阵共有s.length()/T*(numRows-1)列

class Solution {
    public String convert(String s, int numRows) {
        int n = s.length(),r = numRows;
        if(r == 1 || r >= n){
            return s;
        }
        int t = 2*r-2;
        int c = ((n-1)/t + 1) * (r-1);
        char[][] mat = new char[r][c];
        for(int i=0,x=0,y=0;i

时间:击败了14.23%

内存:击败了9.66% 

 解题思路:压缩二维矩阵

因为每次读取都是按行读取,将矩阵每一行初始化为空列表,每次往列表末尾添加字符

class Solution {
    public String convert(String s, int numRows) {
        int n = s.length(),r = numRows;
        if(r == 1 || r >= n){
            return s;
        }
        StringBuffer[] mat = new StringBuffer[r];
        for(int i=0;i

时间:击败了45.67%

内存:击败了72.19% 

28.找出字符串中第一个匹配项的下标

题意:

给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回  -1 

【输入样例】

haystack="sadbutsad",needle="sad"

【输出样例】

0

解题思路:

emmmmm,先暴力枚举哈哈哈。

class Solution {
    public int strStr(String haystack, String needle) {
        int i,j,start;//分别指向haystack和needle字符串
        for(i = 0;i
class Solution {
    public int strStr(String haystack, String needle) {
        //更简洁的代码,参考官方    
        int n = haystack.length(), m = needle.length();
        for (int i = 0; i + m <= n; i++) {
            boolean flag = true;
            for (int j = 0; j < m; j++) {
                if (haystack.charAt(i + j) != needle.charAt(j)) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                return i;
            }
        }
        return -1;
    }
}

/*作者:力扣官方题解
链接:https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string/solutions/732236/shi-xian-strstr-by-leetcode-solution-ds6y/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
*/

 时间:击败了43.29%

内存:击败了34.26%

解题思路:KMP算法

哈哈哈我写不明白,参考b站代码随想录Carl的讲解

帮你把KMP算法学个通透!(理论篇)_哔哩哔哩_bilibili

 int n = haystack.length(),m=needle.length();
        int[] next = new int[m];//前缀数组
        for(int i = 1, j = 0;i 0 && needle.charAt(i) != needle.charAt(j)){
                j = next[j - 1];
            }
            if(needle.charAt(i) == needle.charAt(j)){
                ++j;
            }
            next[i] = j;
        }
        for(int i = 0, j= 0; i < n; ++i){
            while(j > 0 && haystack.charAt(i) != needle.charAt(j)){
                j = next[j-1];
            }
            if(haystack.charAt(i) == needle.charAt(j)){
                ++j;
            }
            if(j == m){
                return i - m + 1;
            }
        }

 时间:击败了100.00%

内存:击败了14.82%

 125.验证回文串

题意:

如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。

字母和数字都属于字母数字字符。

给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 

【输入样例】

s="A man, a plan, a canal:Panama"

【输出样例】

true

解题思路:

双指针判断,记得遇到非字母数字字符跳过。

class Solution {
    public boolean isPalindrome(String s) {
        if(s == null){
            return true;
        }
        s = s.toLowerCase();
        int i=0,j=s.length()-1,flag=1;
        while(i<=j){
            while(i

时间:击败67.53%

内存:击败69.62% 

你可能感兴趣的:(LeetCode,leetcode,面试,算法)