字符串

leetcode125 验证回文串

学到的知识点:字符串转小写方法 s.tolowerCase(),用一个指针对序列做二分。
思路分析:首先只考虑数字和字符,那么就把其他符号去掉。最好的方法就是定义一个新的字符串去保存数字和字符。这里不用去刻意记ASCALL码,因为字符的本质也是个整数。只需要用字符引号把数字和字符引起来即可。之后,用二分法去判断首尾是否相等。用while+双指针的方法最好,思路清晰。用下面这种单指针的方法也可以。

class Solution {
    public boolean isPalindrome(String s) {
        s=s.toLowerCase();
        String sb="";
        for(int i=0;i<s.length();i++){
            char c = s.charAt(i);
            if((c>='0'&&c<='9')||(c>='a'&&c<='z')){
                sb+=c;
            }
        }
        System.out.println(sb);
        int len = sb.length();
        for(int i=0;i<len/2;i++){
            if(sb.charAt(i)!=sb.charAt(len-1-i)){
                return false;
            }
        }
        return true;
    }
}
leetcode14 最长公共前缀

重中之重的一道题
学到的知识点:字符串的indexOf方法,即匹配到的索引位置。
思路分析: 如果这些字符串有一个公共前缀,那么这个前缀必然出现在每一个字符串中。那么就从第一个字符串找。将第一个字符串视为公共前缀,如果不能匹配,就把末尾字符减去,再匹配。第二个字符串匹到以后,再匹配第三个,以此类推。

class Solution {
    public String longestCommonPrefix(String[] strs) {
        if(strs.length==0){
            return "";
        }
        String s=strs[0];
        for(int i=0;i<strs.length;i++){
            while(strs[i].indexOf(s)!=0){
                s=s.substring(0,s.length()-1);
            }
            if(s.isEmpty()){
                return "";
            }
        }
        return s;
    }
}
leetcode3 无重复字符的最长子串

比上一道题还重要
学到的知识点:判断动态字符串长度,用首尾两个指针。首指针是死的,尾指针是活的。当遇到限制条件时,重新设置首指针位置。动态规划求最大。
思路分析: 首先是要求最长子串,那么就符合动态字符串的思路,设置两个指针,一个运动,一个定死。用hashmap键值对来保存字符串和对应位置。当首尾指针指向相同字符串时,求一下长度。因为题目求最大,所以必须保存一下当前长度和之后的子串做对比。用一个变量res保存即可。

class Solution {
    public int lengthOfLongestSubstring(String s) {
        HashMap<Character,Integer> map = new HashMap<>();
        int len = s.length();
        int res=0;
        for(int start=0,end=0;end<len;end++){
            char c = s.charAt(end);
            if(map.containsKey(c)){
               start=Math.max(start,map.get(c));
            }
            map.put(c,end+1);
            res=Math.max(res,end-start+1);
        }
        return res;
    }
}
leetcode 38 外观数列

学到的知识点:字符串拼接。用StringBuffe()类完成字符串的动态增加。
思路分析:产生的字符串由上一个字符串的个数+字符本身产生。设置一个count来统计当前字符,当不同时退出当前统计,完成字符串的拼接,然后统计下一个字符。需要注意的是输入的数字,那么就需要两个for循环,内部for循环来解决一个字符串的拼接。

class Solution {
    public String countAndSay(int n) {
        String s="1";
        for(int i=1;i<n;i++){
            StringBuffer sb = new StringBuffer();
            char c=s.charAt(0);
            int count=1;
            for(int j=1;j<s.length();j++){
                if(s.charAt(j)==c){
                    count++;
                }else{
                    sb.append(count).append(c);
                    count=1;
                    c=s.charAt(j);
                }
        }
        sb.append(count).append(c);
        s=sb.toString();
        }
        return s;
    }
}
leetcode 5 最长回文子串(笔试题的大概难度

解题方法:暴力法/动态规划
1.暴力法
思路:分两步解题。1.求回文子串,2求最长回文子串。步骤1很简单。把步骤1的结果当做一个判断条件,在字符串中从头到尾进行枚举,能找到的最大值就是最终的结果。

public class Solution {

    public String longestPalindrome(String s) {
        int len = s.length();
        if (len < 2) {
            return s;
        }

        int maxLen = 1;
        String res = s.substring(0, 1);
        
        // 枚举所有长度大于等于 2 的子串
        for (int i = 0; i < len - 1; i++) {
            for (int j = i + 1; j < len; j++) {
                if (j - i + 1 > maxLen && valid(s, i, j)) {
                    maxLen = j - i + 1;
                    res = s.substring(i, j + 1);
                }
            }
        }
        return res;
    }

    private boolean valid(String s, int left, int right) {
        // 验证子串 s[left, right] 是否为回文串
        while (left < right) {
            if (s.charAt(left) != s.charAt(right)) {
                return false;
            }
            left++;
            right--;
        }
        return true;
     }
 }
leetcode 383 赎金信(经典中的经典)

判断一个序列中的字符是否可以由另一个序列中的字符完全构成。感觉用到了计数排序的思想。类似 题目:387、451
学到的知识: 统计字符或数组中任意一个字符出现的个数。
思路分析:A序列的字符能否由B序列组成,其实就是统计每个字符的个数,而B的每个字符的个数>=A的每个字符的个数。这个时候,字符成了数组下标,字符个数成了数组内容。之后比较统计大小即可。

class Solution {
    public boolean canConstruct(String ransomNote, String magazine) {
        int[] res = new int[26];
        int[] ans = new int[26];
        for(int i=0;i<ransomNote.length();i++){
            int c = ransomNote.charAt(i)-'a';
            res[c]++;
        }
        for(int i=0;i<magazine.length();i++){
            int c = magazine.charAt(i)-'a';
            ans[c]++;
        }
        for(int i=0;i<26;i++){
            if(res[i]>ans[i]){
                return false;
            }
        }
        return true;
    }
}
leetcode 程序员金典 面试题58.II.左旋转字符串

学到的知识:字符串拼接
思路分析:开始用旋转数组的方法做的,真是昏了头。看到评论区一个大佬的做法,豁然开朗。学东西想深入浅出不容易啊。直接用字符串api拼一下就可以。

class Solution {
    public String reverseLeftWords(String s, int n) {
        return s.substring(n,s.length())+s.substring(0,n);
    }
}
leetcode 1071 字符串的最大公因子

学到的知识:辗转相除法+字符串拼接
思路分析:首先判断两个字符串的内容是否一致。直接相互拼接一下,判断是否相同即可,完全不用挨个遍历。如果不同,直接就false。如果相同,就需要判断A和B能否整除了。用辗转相除法(a,b两个数求最大公因子的方法:b作为被除数,a%b作为除数,一路递归)

class Solution {
    public String gcdOfStrings(String str1, String str2) {
        if(!(str1+str2).equals(str2+str1)){
            return "";
        }
        return str1.substring(0,gcd(str1.length(),str2.length()));
    }
    private int gcd(int a,int b){
        return b==0?a:gcd(b,a%b);
    }
}

还有58题.最后一个单词的长度,用一个s.split()这个方法就可以。需要注意的是,split(" ")需为双引号,已经搞错很多回了。

只做了这么多,很多经典的题根本就没有刷到。基础不好,大量的时间都用在补基础上了。
路漫漫其修远兮

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值