字符串题解(leetcode,持续更新中)

字符串题解(leetcode,持续更新中)

leetcode 3 无重复字符的最长子串

题目

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:

输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:

输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:

输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
示例 4:

输入: s = ""
输出: 0

分析

这道题主要用到了滑动窗口的思想

max定义为 最大不重复子串的长度,
left是滑动窗口的左指针,i是滑动窗口的右指针
	定义一个hashmap ,用于存储字符以及字符的位置
		对字符串中所有字符进行遍历
			判断当前字符i 是否在hashmap中
				如果在,需要更新滑动窗口的左指针
					left=Math.max(left,map.get(s.charAt(i))+1);
            无论左指针是否更新,都要更新 s.charAt(i)的位置
            将s.charAt(i),存入hashmap中
            重新计算此时的max
		遍历完成,返回max即可
时间复杂度O(n)

代码

class Solution{
    public int lengthOfLongestSubstring(String s){
        if(s.length()==0) return 0;
        HashMap<Character,Integer> map = new HashMap<Character,Integer>();//存储字符以及字符的位置
        int max=0;//用于记录最大不重复子串的长度
        int left=0;//滑动窗口左指针
        for(int i=0;i<s.length();i++){//遍历整个字符串
            if(map.containsKey(s.charAt(i))){ //判断当前字符是否在map中
                //如果字符已经存在了,则更新左下标,向右移动一个字符
                left=Math.max(left,map.get(s.charAt(i))+1);
            }
            map.put(s.charAt(i),i);//如果不包含,则将字符添加到map(字符,字符在数组下标),如果包含也需要更新s.charAt(i)的位置为当前的i,所以无论left是否有更新,都需要更新s.charAt(i)的位置
            max=Math.max(max,i-left+1);//此时不重复子串的长度为:i-left+1,与原来的max相比,取最大值。
        }
        return max;
    }
}

leetcode 17 电话号码的字母组合

题目

给定一个仅包含数字 2-9的字符串,返回所有能表示的字母组合。答案可以按任意顺序返回
	类似于9键键盘

示例 1:

输入:digits = "23"
输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
示例 2:

输入:digits = ""
输出:[]
示例 3:

输入:digits = "2"
输出:["a","b","c"]

分析

用二叉树来实现,转换为求二叉树的所有路径

代码


leetcode 20 有效的括号

题目

给定一个只包括 '('')''{''}''['']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。

分析

用栈实现

代码

class Solution {
    public boolean isValid(String s) {
        if(s.isEmpty())
            return true;//字符串为空
        Stack<Character> stack=new Stack<Character>();;//字符串-栈   
        for(char c:s.toCharArray()){//遍历字符串中的元素
            if(c=='(')
                stack.push(')');//如果传入的是左括号,则同时也将与之对应的右括号入栈
            else if(c=='{')
                stack.push('}');//同上
            else if(c=='[')
                stack.push(']');//同上
            else if(stack.empty()||c!=stack.pop())//栈顶元素与c不同,则说明字符串无效
                return false;
        }
        return stack.isEmpty();//栈中为空,则说明字符串有效,反之无效
    }
}

leetcode 22 括号生成

题目

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

有效括号组合需满足:左括号必须以正确的顺序闭合。

输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]

输入:n = 1
输出:["()"]

分析

递归

代码

class Solution{
    List<String> res =new ArrayList<>();
    public List<String> generateParenthesis(int n){
        if(n<=0){
            return res;//返回最终的结果
        }
        getParenthesis("",n,n);//递归开始
        return res;
    } 
    private void getParenthesis(String str,int left,int right){
        if(left ==0 && right ==0){
            res.add(str);
            return;
        }
        if(left==right){
            //剩余左右括号数相等,下一个只能用左括号
            getParenthesis(str+"(",left-1,right);
        }else if(left<right){
            //剩余左括号小于右括号,下一个可以用左括号也可用右括号
            if(left>0){
                getParenthesis(str+"(",left-1,right);
            }
            getParenthesis(str+")",left,right-1);
        }
    }
}

leetcode 49 字母异位词分组

题目

分析

代码

leetcode 139 单词拆分

题目

给定一个非空字符串 s 和一个包含非空单词的列表 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。

说明:

拆分时可以重复使用字典中的单词。
你可以假设字典中没有重复的单词。
示例 1:

输入: s = "leetcode", wordDict = ["leet", "code"]
输出: true
解释: 返回 true 因为 "leetcode" 可以被拆分成 "leet code"。
示例 2:

输入: s = "applepenapple", wordDict = ["apple", "pen"]
输出: true
解释: 返回 true 因为 "applepenapple" 可以被拆分成 "apple pen apple"。
     注意你可以重复使用字典中的单词。

分析

动态规划

代码

class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        boolean [] dp = new boolean[s.length()+1];
        dp[0] = true;
        for(int i=1;i<=s.length();i++){
            for(String  word:wordDict){
                int sz=word.length();
                if(i-sz>=0 && s.substring(i-sz,i).equals(word)){
                    dp[i]=dp[i]||dp[i-sz];
                }
            }
        }
        return dp[s.length()];
    }
}

leetcode 208 实现trie(前缀树)

题目

rie,又称前缀树或字典树,是一棵有根树,其每个节点包含以下字段:

指向子节点的指针数组 \textit{children}children。对于本题而言,数组长度为 2626,即小写英文字母的数量。此时 \textit{children}[0]children[0] 对应小写字母 aa,\textit{children}[1]children[1] 对应小写字母 bb,…,\textit{children}[25]children[25] 对应小写字母 zz。
布尔字段 \textit{isEnd}isEnd,表示该节点是否为字符串的结尾。

代码

class Trie{
    class TireNode{
        private boolean isEnd;//变量
        TireNode[] next;
        
        public TireNode(){//方法
            isEnd = false;
        	next =new TireNode[26];
        }
    }
    
    private TireNode root;//根节点
    public Trie(){
        root = new TireNode();
    }
    
    //插入
    public void insert(String word){
        TireNode node =root;
        for(char c:word.toCharArray()){
            if(node.next[c-'a'] == null){
                node.next[c-'a'] = new TireNode();
            }
            node=node.next[c-'a'];
        }
        node.isEnd = true;
    }
    
    
    //查找
    public boolean search(String word){
        TireNode node =root;
        for(char c:word.toCharArray()){
            node = node.next[c-'a'];
            if(node==null){
                return false;//没找到
            }
        }
        return node.isEnd;
    }
    
    public boolean startsWith(String prefix) {
        TireNode node = root;
        for (char c : prefix.toCharArray()) {
            node = node.next[c - 'a'];
            if (node == null) {
                return false;
            }
        }
        return true;
    }
}

leetcode 394 字符串解码

题目

给定一个经过编码的字符串,返回它解码后的字符串。

编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。

你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。

此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。

分析

示例 1:

输入:s = "3[a]2[bc]"
输出:"aaabcbc"
示例 2:

输入:s = "3[a2[c]]"
输出:"accaccacc"
示例 3:

输入:s = "2[abc]3[cd]ef"
输出:"abcabccdcdcdef"
示例 4:

输入:s = "abc3[cd]xyz"
输出:"abccdcdcdxyz"

代码


leetcode 438 找到字符串中所有字母异位词

题目

给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。

异位词 指字母相同,但排列不同的字符串。

示例 1:

输入: s = "cbaebabacd", p = "abc"
输出: [0,6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的异位词。
 示例 2:

输入: s = "abab", p = "ab"
输出: [0,1,2]
解释:
起始索引等于 0 的子串是 "ab", 它是 "ab" 的异位词。
起始索引等于 1 的子串是 "ba", 它是 "ab" 的异位词。
起始索引等于 2 的子串是 "ab", 它是 "ab" 的异位词。

分析

滑动窗口法+双指针

代码


leetcode 647 回文子串

题目

给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。
回文字符串 是正着读和倒过来读一样的字符串。
子字符串 是字符串中的由连续字符组成的一个序列。
具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被视作不同的子串。

示例 1:

输入:s = "abc"
输出:3
解释:三个回文子串: "a", "b", "c"
示例 2:

输入:s = "aaa"
输出:6
解释:6个回文子串: "a", "a", "a", "aa", "aa", "aaa"

分析

动态规划
    boolean[][] dp=new Boolean[s.length()][s.length()];
    s.charAt(i)==s.charAt(j)&&(dp[i][j]=dp[i+1][j-1]||i-j<=2);

代码

class Solution {
    public int countSubstrings(String s) {
        boolean[][] dp=new boolean[s.length()][s.length()];
        int ans=0;
        for(int j=0;j<s.length();j++){
            for(int i=0;i<=j;i++){
                if(s.charAt(i)==s.charAt(j)&&(j-i<2||dp[i+1][j-1])){ 
                    dp[i][j]=true;
                    ans++;
                }
            }
        }
        return ans;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值