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(" ")需为双引号,已经搞错很多回了。
只做了这么多,很多经典的题根本就没有刷到。基础不好,大量的时间都用在补基础上了。
路漫漫其修远兮