LeetCode日记——【数据结构】字符串专题
题1:两个字符串包含的字符是否完全相同
难度:Easy
题目描述:
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
示例 1:
输入: s = "anagram", t = "nagaram"
输出: true
代码:
1 class Solution { 2 public boolean isAnagram(String s, String t) { 3 int[] cnts = new int[26]; 4 for(char c:s.toCharArray()){ 5 cnts[c-'a']++; 6 } 7 for(char c:t.toCharArray()){ 8 cnts[c-'a']--; 9 } 10 for(int i:cnts){ 11 if(i!=0) return false; 12 } 13 return true; 14 } 15 }
分析:
创建一个容量为26的数组。对应索引的位置的数字表示字符串中的字符的个数。比较两个字符串所生成的数组是否相同,即可判断这两个数组是否为字母异味词。代码中先生成s的数组,然后按位减去t生成的数组,若最后的数组有不为0的元素,则表示不为字母异位词。
toCharArray()方法可将一个字符串转化成数据类型为字符的数组。
题2:最长回文串
难度:Easy
题目描述:
给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串。
在构造过程中,请注意区分大小写。比如 "Aa" 不能当做一个回文字符串。
注意:
假设字符串的长度不会超过 1010。
示例 1:
输入:
"abccccdd"
输出:
7
解释:
我们可以构造的最长的回文串是"dccaccd", 它的长度是 7。
代码:
1 class Solution { 2 public int longestPalindrome(String s) { 3 int[] cnts = new int[256]; 4 for(char c:s.toCharArray()){ 5 cnts[c]++; 6 } 7 int palindrome=0; 8 for(int cnt:cnts){ 9 palindrome+=(cnt/2)*2; 10 } 11 if(palindrome<s.length()) palindrome++; 12 return palindrome; 13 } 14 }
分析:
将字符串对应的字母的出现次数存放在数组cnts中,数组中索引(ascii码)位置表示对应的字母出现的次数。
对于每个字符,取能够够成回文串的个数,加到变量palindrome中(偶数即为本身,奇数须减一)。
最后考虑到回文串可以允许最中间出现一个单独字符,因此判断如果存在单个字符,就将palindrome加1。最后返回palindrome即可。
题3:同构字符串
难度:Easy
题目描述:
给定两个字符串 s 和 t,判断它们是否是同构的。
如果 s 中的字符可以被替换得到 t ,那么这两个字符串是同构的。
所有出现的字符都必须用另一个字符替换,同时保留字符的顺序。两个字符不能映射到同一个字符上,但字符可以映射自己本身。
示例 1:
输入: s = "egg", t = "add"
输出: true
代码:
1 class Solution { 2 public boolean isIsomorphic(String s, String t) { 3 int[] scount = new int[256]; 4 int[] tcount = new int[256]; 5 for(int i=0;i<s.length();i++){ 6 char sc = s.charAt(i); 7 char tc = t.charAt(i); 8 if(scount[sc]!=tcount[tc]) return false; 9 scount[sc]=i+1; 10 tcount[tc]=i+1; 11 } 12 return true; 13 } 14 }
分析:
字符串类型的题目套路都是建立数组,字母(ascii码)作为数组的索引来进行各种操作。
本题中,为两个字符串分别建立两个数组。分别取出字符串中相同位置的字符,若两个数组中相应字符位置的值(第一次循环时均为0)不同,则直接返回false。然后给两个数组中相应字符位置赋值i+1,表示本轮当前字符分别出现在两个字符串中的第i+1位。这样做的目的是在以后的循环中,再次出现该字母,就可以查看该字母上一次出现的位置,从而判断两字符串结构是否相同。这里也可以是i+2,i+3等,但就是不能为i,因为这样就跟一开始的初始值0重复了。
题4:回文子串
难度:Medium
题目描述:
给定一个字符串,你的任务是计算这个字符串中有多少个回文子串。
具有不同开始位置或结束位置的子串,即使是由相同的字符组成,也会被计为是不同的子串。
示例 1:
输入: "aaa"
输出: 6
说明: 6个回文子串: "a", "a", "a", "aa", "aa", "aaa".
代码:
1 class Solution { 2 int counts; 3 public int countSubstrings(String s) { 4 for(int i=0;i<s.length();i++){ 5 //奇数个数的回文子串 6 extendSubstrings(s,i,i); 7 //偶数个数的回文子串 8 extendSubstrings(s,i,i+1); 9 } 10 return counts; 11 } 12 13 private void extendSubstrings(String s,int start,int end){ 14 while(start>=0 && end<s.length() && s.charAt(start)==s.charAt(end)){ 15 //扩展字符串 16 start--; 17 end++; 18 //回文子串计数加一 19 counts++; 20 } 21 } 22 }
分析:
写一个单独的方法extendsSubstrings(),作用是对于一个字符串s,指定两个初始位置,判断两个位置的字母是否相同,然后逐渐向两边扩展,每次扩展都记录counts数,直到不满足要求为止(有一边到头了或者两边字母不一样了)。
然后我们对原字符串的每一个位置进行extendsSubstrings()操作,注意因为扩展是2位2为扩展的,因此字符为奇数个数的子串和偶数个数的子串要分别计算,最后返回counts即可。
题5:回文数
难度:Easy
题目描述:
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
示例 1:
输入: 121
输出: true
示例 2:
输入: -121
输出: false
解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
代码:
1 class Solution { 2 public boolean isPalindrome(int x) { 3 if(x==0) return true; 4 if(x<0||x%10==0) return false; 5 6 int right = 0; 7 while (x > right) { 8 //right为右边数起的数的转置,每次循环多数一位 9 right = right * 10 + x % 10; 10 //左数部分,每次循环少一位 11 x /= 10; 12 } 13 //对于偶数位数,判断x==right 14 //对于奇数位数,判断x == right / 10 15 return x == right || x == right / 10; 16 } 17 }
分析:
首先判断特殊情况。若x为0,直接返回true。若x为负数或为10的倍数,直接返回false。注意要先判断x是否为0,因为0也是10的倍数。
定义一个变量right。计算right为x右边部分的转置,x每次少一位。x<=right时结束循环。
最后判断时,分为两种情况。若x原本有偶数位数字,则最后若x是回文数,x应该==right。若x原本有奇数位数字,则最后若x是回文数,x应该==right/10。
题6:计数二进制子串
难度:Easy
题目描述:
给定一个字符串 s,计算具有相同数量0和1的非空(连续)子字符串的数量,并且这些子字符串中的所有0和所有1都是组合在一起的。
重复出现的子串要计算它们出现的次数。
示例 1 :
输入: "00110011"
输出: 6
解释: 有6个子串具有相同数量的连续1和0:“0011”,“01”,“1100”,“10”,“0011” 和 “01”。
请注意,一些重复出现的子串要计算它们出现的次数。
另外,“00110011”不是有效的子串,因为所有的0(和1)没有组合在一起。
代码:
1 class Solution { 2 public int countBinarySubstrings(String s) { 3 int preLen = 0, curLen = 1, count = 0; 4 for (int i = 1; i < s.length(); i++) { 5 if (s.charAt(i) == s.charAt(i - 1)){ 6 curLen++; 7 } else { 8 preLen = curLen; 9 curLen = 1; 10 } 11 if (preLen >= curLen) { 12 count++; 13 } 14 } 15 return count; 16 } 17 }
分析:
这答案我真的没看懂。。。
字符串专题完结撒花~