LeetCode刷题之String篇

3. Longest Substring Without Repeating CharactersCode it now! https://leetcode.com/problems/longest-substring-without-repeating-characters/难度:medium问题描述:给定字符串,找出最长没有重复字符的子串。必须是子串,而不是序列
摘要由CSDN通过智能技术生成
3. Longest Substring Without Repeating Characters

Code it now! https://leetcode.com/problems/longest-substring-without-repeating-characters/

难度:medium


问题描述:

给定字符串,找出最长没有重复字符的子串。

必须是子串,而不是序列。

解题思路:

  dp算法:时间复杂度O(n),空间复杂度O(n)。

    本题用到了map作为重复元素位置的更新,用到了双指针,一个用来遍历String中的每个元素,另一个用来记录当前字符出现最新位置。dp递推公式为max=Math.max(max,i-j+1);代码如下:

 

class Solution {
    public int lengthOfLongestSubstring(String s) {
        if (s.length() == 0) return 0;
        HashMap<Character,Integer> map = new HashMap<Character,Integer>();
        int max = 0;
        //i指针用来遍历String,j指针用来记录重复出现元素的最新位置,用来更新位置。
        for(int i=0,j=0;i<s.length();i++)
        {
            if(map.containsKey(s.charAt(i))){
                //如果出现重复字符,j指针就会更新至遍历到i为止,没有出现重复字符的最右位置。 比如abba,j如果不取j和重复出现元素的最大值的话,当i=3时,j=0+1=1,最后计算出的最大子串长度就为3,因此还是要从j=2的位置算起。
                j = Math.max(j,map.get(s.charAt(i))+1);
                //j = map.get(s.charAt(i))+1;   错误!
            }
            map.put(s.charAt(i),i);
            //动态规划方程。
            max = Math.max(max,i-j+1);
        }
        return max;
    }
}




17. Letter Combinations of a Phone Number

Code it now! https://leetcode.com/problems/letter-combinations-of-a-phone-number/

难度:medium


问题描述:

给定数字字符串,返回数字可能表示的所有可能的字母组合。

数字到字母映射如下。


解题思路:

  回溯算法:时间复杂度O(2^n),空间复杂度O(1)。

 本题使用了回溯思想分三步求解:

  1.针对问题,确定解空间(明确定义问题解空间)。

  2.确定结点的子解终止条件。

  3.一般以深度优先搜索解空间。

 

class Solution {
    static String[] letterMap = {
        " ",       //0
        "",        //1
        "abc",     //2
        "def",     //3
        "ghi",     //4
        "jkl",     //5
        "mno",     //6
        "pqrs",    //7
        "tuv",     //8
        "wxyz"     //9
    };
    
    public static List<String> res = null;
    
    public List<String> letterCombinations(String digits) {
        //树形问题 
        res = new ArrayList<String>();
        if(digits.equals("")){
            return res;
        }
        //针对问题,确定解空间。
        findCombination(digits,0,"");
        return res;
    }
    //s中保存了从[0...index-1]翻译得到的一个字母字符串
    //寻找和digits[index]匹配的字母,获得digits[0...index]翻译得到的解
    public static void findCombination(String digits,int index,String s){
        //2.确定结点的子解终止条件。
        if(index==digits.length()){
            res.add(s);
            //此处则是已遍历完digits,因此不再进入下面的操作,而且需要return终止递归调用。
            return ;
        }
        
        char c = digits.charAt(index);
        String letters = letterMap[c-'0'];
        //递归操作不断新添新元素至s当中。 这是组合问题,不需要回退一步。是找出所有组合  深度优先遍历
        for(int i=0;i<letters.length();i++)
            findCombination(digits,index+1,s+letters.charAt(i));
    }
}





20. Valid Paraenttheses

Code it now! https://leetcode.com/problems/valid-parentheses/

难度:easy


问题描述:

括号匹配。

解题思路:

  dp算法:时间复杂度O(n),空间复杂度O(n)。

 本题使用栈Stack来实现的括号匹配,思路是当遇到左括号({[时,进行压栈操作,当遇到右括号)}]时,进行出栈匹配操作,如果不能匹配返回false,全部都能匹配最后返回true,代码如下:

 

class Solution {
    public boolean isValid(String s) {
        Stack<Character> stack = new Stack<Character>();
        for(int i=0;i<s.length();i++){
            //遍历整个string,如果遇到左括号({[时,进行入栈操作。
            if(s.charAt(i)=='('||s.charAt(i)=='{'||s.charAt(i)=='[')
                stack.push(s.charAt(i));
            else{
                //如果遇到右括号)}]时,进行出栈匹配操作,首先判断栈是否为空,不为空进行match操作,最后判断是否成功配对。
                if(stack.size()==0)
                    return false;
                
                char c = stack.peek();
                stack.pop();
                    
                char match;
                if(s.charAt(i)==')'){
                    match = '(';
                }else if(s.charAt(i)=='}'){
                    match = '{';
                }else{
                    assert(s.charAt(i)==']');
                    match = '[';
                }
                if(c!=match){
                    return false;
                }
            }
        }
        if(stack.size()==0) return true;
        else return false;
    }
}






58. Length of Last Word

Code it now! https://leetcode.com/problems/length-of-last-word/

难度:easy


问题描述:

给定一个字符串由大写小写空格字符组成,返回字符串中最后一个单词长度,如果最后一个字符不存在则返回0。

解题思路:

  String库函数算法:时间复杂度O(1),空间复杂度O(1)。

 本题首先需要分析这个字符串,第一步是去除字符串前后的空格,第二步是找到最后一个空格的索引,第三步使用字符串总长度减去这个索引,即为最后一个单词的长度。代码如下:

class Solution {
    public int lengthOfLastWord(String s) {
        s = s.trim();
        int lastIndex = s.lastIndexOf(' ') +1;
        return s.length() - lastIndex;
    }
}







67. Add Binary

Code it now! https://leetcode.com/problems/add-binary/

难度:easy


问题描述:

给定两个二进制字符串,返回它们的和(也是二进制字符串)。

解题思路:

  进位算法:时间复杂度O(n),空间复杂度O(1)或者O(n)。

 本题可能大家一开始的想法是把两个二进制转换成十进制相加,然后再转为二进制输出结果。但是这里用到的是一种适合任何两个数相加的一种策略,在这简单的叫做进位法,从最右位数开始相加,该进位则进位的思想(这里需要注意的是进位的处理。使用到了count来统计进位)。代码如下:

class Solution {
    public String addBinary(String a, String b) {
        //第一步:把字符串转换成字符数组。
        char[] c1 = a.toCharArray();
        char[] c2 = b.toCharArray();
        int len_a = a.length()-1;
        int len_b = b.length()-1;
        int index = 0;
        StringBuffer sb = new StringBuffer();
        while(len_a>=0||len_b>=0||index==1){
            //判断是否走到了字符数组尽头,如果是则赋值0,不是则取出值。
            int num1 = len_a>=0? c1[len_a]-'0':0;
            int num2 = len_b>=0? c2[len_b]-'0':0;
            int count = num1+num2;
            //此处分三种情况讨论,见判断条件。
            if(count+index==3){
                index = 1;
                sb.append(1);
            }else if(count+index==2){
                index = 1;
                sb.append(0);
            }else{
                sb.append(count+index);
                index = 0;
            }
            len_a--;
            len_b--;
        }
        return sb.reverse().toString(); 
    }
}






344. Reverse String

Code it now! https://leetcode.com/problems/reverse-string/

难度:easy


问题描述:

反转给定字符串。

解题思路:

  StringBuilder库函数算法:时间复杂度O(1),空间复杂度O(1)。

 String中没有对字符串反转的库方法,但是StringBuilder提供了丰富的库方法,此处主要利用到库函数去处理问题。

  简单代码如下:

class Solution {
    public String reverseString(String s) {
        StringBuffer sb = new StringBuffer();
        sb.append(s);
        return sb.reverse().toString();       
    }
}

 如果不使用库方法,我们又是如何实现的字符串反转呢? 下面的方法实现在leetcode中显示超时。。。

class Solution {
    public String reverseString(String s) {
        String str = "";
        for(int i=s.length()-1;i>=0;i--)
        {
            str += s.charAt(i);
        }
        return str;
    }
}
 于是对比,可以发现stringbuilder反转实现比这个好。str+这个操作很消耗时间。进一步又想到了采用双指针的方式去反转这个字符串。代码如下:

 

class Solution {
    public String reverseString(String s) {
        char[] c = s.toCharArray();
        int i = 0;
        int j = s.length()-1;
        while(i<j)
        {
            char temp = c[i];
            c[i] = c[j];
            c[j] = temp;
            i++;
            j--;
        }
        return new String(c);
    }
}



















  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值