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 }

 分析:

这答案我真的没看懂。。。

 

字符串专题完结撒花~

 

posted @ 2020-06-02 20:02  菅兮徽音  阅读(219)  评论(0编辑  收藏  举报