LeetCode总结字符串操作类题目

反转字符串

题目:https://leetcode.com/problems/reverse-string/

武器:两个指针

二次结果:一次pass

判断是否互为变位词

题目:https://leetcode.com/problems/valid-anagram/

武器:hashmap统计第一词语每个字符次数,遍历第二个,每个次数减去1,不需要判断是否存在。最后map有不为0,则false

二次结果:通过

是否有效的括号输入

题目:https://leetcode.com/problems/valid-parentheses/

武器:利用stack判断。但是写错了,以为正确输入必定是对称的,直到测试case出现 ()[]{},我发现我判断条件就错了。不一定是对称的。所以修改思路,发现是({[三个其中任意一个,入stack,如果不是出stack,stack出来的栈顶元素和当前拼接(注意char不能直接用+,会成为数字的,转为string相加),判断是否是()或者[]或者{},如果三者都不是返回false,反之continue。最后判断stack是否为空决定最后结果。因为如果是合法输入,根据规则,入stack的元素和不入stack的元素个数应该是相等的。写到这里,我用map统计个数是否可以?当然不可以,因为无法保证顺序!!!

重新看了一下原来的解法,感觉原来的思路清晰一些。

1 遍历string,判断stack是否为空

2 如果stack为空,没有可以比较对象,直接入stack

3 如果stack不为空,peek栈顶元素进行比较,如果符合成对情况,pop出stack 顶元素,否则入stack。

4 最后判断stack是否为空,判断是否合法输入

总结一些,利用stack来trace整个输入,其实不区分左边还是右边,因为最后stack必定为空才能合法输入。效率比我的差一点,但是代码相对简洁一些。

结果:新思路通过,但是代码调试修改一些漏洞,略显复杂

最长公共前缀

题目:https://leetcode.com/problems/longest-common-prefix/

武器:修改为二分查找,思路没有记住。首先寻找长度最短的字符串,然后开始折半查找,判断截止到当前mid的字串是不是公共前缀(循环判断每个字符串startWith),如果是low=mid+1,反之high=mid-1;注意返回结果是 return  minShortString.substring(0,(low+high)/2);

结果:未通过

Group Anagrams

题目:https://leetcode.com/problems/group-anagrams/

武器:1. 排序,注意for循环的时候对当前字符串排序,然后map寻找,value是list,存在把原字符串加入list

            2. 为了不排序,降低时间复杂度,可以找到一种判断是错位符的方式。计算和不行,因为可能性很多。每个字符串,循环处理,每个字符减去a,得到的数字进行桶排序, count[curr.charAt(j)-'a']++;

然后bucket数组从头到尾拼接起来,就可以比较是否是错位符了。

Longest Palindromic Substring

题目:https://leetcode.com/problems/longest-palindromic-substring/

武器:动态规划

结果:思路正确,结构也差不多,关键错误点有两个:第一个第二层循环j从i开始往前找,i是从头往后遍历。

状态转化我是判断正确的,一个是dp[j][i]为ture的条件是str.charAt[j]==str.charAt[i]并且(i-j<2||dp[j+1][i-1]。如果dp[j][i]为true,计算长度是否大于res临时变量,如果大与,计算subString就可以。

状态转化方程没有问题,问题是两层for循环,我这种写法如果是“aaaa”,发现dp[1][2]没有填充成true。因为此时i=0;所以我的写法有问题。为了保证ij之前都填充过值,所以需要这样写for循环,

class Solution {
    public String longestPalindrome(String s) {
        if(s.length()==0){
            return s;
        }
        int n=s.length();
        boolean[][] dp=new boolean[n][n];
        String res=null;
         for (int i = 0; i < n; i++) {
            for (int j = i; j >= 0; j--) {
                if(s.charAt(i)==s.charAt(j)&&(i-j<2||dp[j+1][i-1])){
                    dp[j][i]=true;
                    if (res == null || i - j + 1 > res.length()) {
                        res = s.substring(j, i + 1);
                    }
                }
                
            }
            
        }
        return res;
        
    }
}

我的错误的for循环 

class Solution {
    public String longestPalindrome(String s) {
        if(s.length()==0){
            return s;
        }
        int n=s.length();
        boolean[][] dp=new boolean[n][n];
        String res="";
        for(int i=0;ires.length()?curr:res;
                }
                
            }
            
        }
        return res;
        
    }
}

 

Longest Substring Without Repeating Characters

题目:https://leetcode.com/problems/longest-substring-without-repeating-characters/submissions/

武器:滑动窗口,其实应该也可以用dp解决,不过这样简单。j负责往后扩展,i是左侧起始位置。如果新的元素不在set,j++,计算最新的最大长度,如果新的重复,已经在set中,从set中移除i指向的元素,i++,移动一位

 

class Solution {
    public int lengthOfLongestSubstring(String s) {
         int n = s.length();
         int res=0;
         int i=0;int j=0;
         Set set = new HashSet<>();
         while(i

 

你可能感兴趣的:(架构设计,Leetcode算法)