数据结构与算法学习⑪(字符串算法
数据结构与算法学习⑪(字符串算法)
709. 转换成小写字母
解法1:使用内置API,不推荐
解法2:ASCCII码操作
在线ASCCII对照表
发现:
a-z:97-122
A-Z:65-90
0-9:48-57
大写字母和小写字母之间差了32,故,遍历字符串中的每个字符,如果是大小字母,加上32即可
class Solution {
public String toLowerCase(String str) {
char[]result= str.toCharArray();
for(int i=0;i<result.length;i++){
if(result[i]>='A'&&result[i]<='Z'){
result[i]+=32;
}
}
return new String(result);
}
}
解法3:位运算
基于ASCCII码的区别,使用位运算的技巧。
- 大写变小写、小写变大写:字符 ^= 32;
异或操作的另一种理解方式:不进位加法
class Solution {
public String toLowerCase(String str) {
char[]result= str.toCharArray();
for(int i=0;i<result.length;i++){
if(result[i]>='A'&&result[i]<='Z'){
result[i]|=32;
}
}
return new String(result);
}
}
58. 最后一个单词的长度
class Solution {
public int lengthOfLastWord(String s) {
int count=0;
int right=s.length()-1;
while(right>=0&&s.charAt(right)==' '){
right--;
}
while(right>=0&&s.charAt(right)!=' '){
right--;
count++;
}
return count;
}
}
771. 宝石与石头
解法1:暴力,遍历S,对于 S 中的每个字符,遍历一次字符串 J,如果其和 J 中的某一个字符相同,
则是宝石。—不推荐
解法2:哈希集合
此处只需要用一个基础的数组即可,因为题设条件说了: J 中的字母不重复, J 和 S 中的所有字
符都是字母。字母区分大小写。
搞一个数组存放64个,也就是大小写所有的位置,然后遍历查看
class Solution {
public int numJewelsInStones(String jewels, String stones) {
int[]hash=new int[64];
char[]js=jewels.toCharArray();
for(char c:js){
hash[c-'A']++;
}
int count=0;
char[]s=stones.toCharArray();
for(int i=0;i<s.length;i++){
if(hash[s[i]-'A']!=0){
count++;
}
}
return count;
}
}
387. 字符串中的第一个唯一字符
387. 字符串中的第一个唯一字符
题意说明: 第一个不重复的字符,并非指字符串中前后两个字符不重复, 这里的意思是: 对于某个字母,
它在整个字符串中是否有重复的,
解法1: 哈希表辅助,两次遍历,一次遍历求出现的频率,二次遍历找第一个出现频率为1的字符
class Solution {
public int firstUniqChar(String s) {
int[]hash=new int[32];
char[]strs=s.toCharArray();
for(char str:strs){
hash[str-'a']++;
}
for(int i=0;i<strs.length;i++){
if(hash[strs[i]-'a']==1){
return i;
}
}
return -1;
}
}
14. 最长公共前缀
分治+前缀比较
class Solution {
public String longestCommonPrefix(String[] strs) {
if(strs.length==0||strs==null){
return "";
}
return findfix(strs,0,strs.length-1);
}
public String findfix(String[] strs,int start,int end){
if(start>=end){
return strs[start];
}
int mid=((end-start)>>1)+start;
String left=findfix(strs,start,mid);
String right=findfix(strs,mid+1,end);
return fix(left,right);
}
public String fix(String left,String right){
StringBuilder sb=new StringBuilder();
int smallLength=left.length()>=right.length()?right.length():left.length();
for(int i=0;i<smallLength;i++){
if(left.charAt(i)!=right.charAt(i)){
break;
}
sb.append(left.charAt(i));
}
return sb.toString();
}
}
下面这个不用Stringbuilder拼接,更省空间
class Solution {
public String longestCommonPrefix(String[] strs) {
if (strs == null || strs.length == 0) {
return "";
} else {
return longestCommonPrefix(strs, 0, strs.length - 1);
}
}
public String longestCommonPrefix(String[] strs, int start, int end) {
if (start == end) {
return strs[start];
} else {
int mid = (end - start) / 2 + start;
String lcpLeft = longestCommonPrefix(strs, start, mid);
String lcpRight = longestCommonPrefix(strs, mid + 1, end);
return commonPrefix(lcpLeft, lcpRight);
}
}
public String commonPrefix(String lcpLeft, String lcpRight) {
int minLength = Math.min(lcpLeft.length(), lcpRight.length());
for (int i = 0; i < minLength; i++) {
if (lcpLeft.charAt(i) != lcpRight.charAt(i)) {
return lcpLeft.substring(0, i);
}
}
return lcpLeft.substring(0, minLength);
}
}
151. 翻转字符串里的单词
class Solution {
public String reverseWords(String s) {
StringBuilder sb=new StringBuilder();
way(s,sb,0);
return sb.toString().trim();
}
public void way(String s,StringBuilder sb,int left){
while(left<s.length()&&s.charAt(left)==' '){
left++;
}
if(left==s.length()){
return;
}
int right=left;
while(right<s.length()&&s.charAt(right)!=' '){
right++;
}
way(s,sb,right);
sb.append(s,left,right).append(" ");
}
}
还有一些加油
344. 反转字符串
345. 反转字符串 II
346. 反转字符串中的单词 III
347. 仅仅反转字母
348. 验证回文串
349. 验证回文字符串 Ⅱ
10. 正则表达式匹配
class Solution {
public boolean isMatch(String s, String p) {
char[]ss=s.toCharArray();
char[]pp=p.toCharArray();
return isMatch(ss,0,pp,0);
}
public boolean isMatch(char[]ss,int left,char[]pp,int right){
if(pp.length==right){
return left==ss.length;
}
boolean isMatch=left<ss.length&&(ss[left]==pp[right]||pp[right]=='.');
//左边的判断条件是防止越界
if(pp.length-right>=2&&pp[right+1]=='*'){
//第一种是为0,也就是直接跳过a和*,匹配后面的
//第二章是往后匹配
return isMatch(ss,left,pp,right+2)||(isMatch&&isMatch(ss,left+1,pp,right));
}
return isMatch&&isMatch(ss,left+1,pp,right+1);
}
}
dp
class Solution {
public boolean isMatch(String s, String p) {
char[]ss=s.toCharArray();
char[]pp=p.toCharArray();
boolean [][] dp = new boolean[ss.length+1][pp.length+1];
dp[0][0]=true;
for(int k=0;k<pp.length;k++){
if(pp[k]=='*'&&dp[0][k-1]){
dp[0][k+1]=true;
}
}
for(int i=1;i<=ss.length;i++){
for(int j=1;j<=pp.length;j++){
if(ss[i-1]==pp[j-1]||pp[j-1]=='.'){
dp[i][j]=dp[i-1][j-1];
}else if(pp[j-1]=='*'){
if(pp[j-1-1]==ss[i-1]||pp[j-1-1]=='.'){
dp[i][j]=dp[i-1][j]||dp[i][j-2];
}else{
dp[i][j]=dp[i][j-2];
}
}
}
}
return dp[ss.length][pp.length];
}
}
115. 不同的子序列
class Solution {
public int numDistinct(String s, String t) {
char[]ss=s.toCharArray();
char[]tt=t.toCharArray();
int n=ss.length;
int m=tt.length;
int[][]dp=new int[n+1][m+1];
for(int k=0;k<m;k++){
dp[k][0]=1;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(ss[i-1]==tt[j-1]){
dp[i][j]=dp[i-1][j-1]+dp[i-1][j];
}else{
dp[i][j]=dp[i-1][j];
}
}
}
return dp[n][m];
}
}
压缩一下
class Solution {
public int numDistinct(String s, String t) {
char[]ss=s.toCharArray();
char[]tt=t.toCharArray();
int m=ss.length;
int n=tt.length;
int[]dp=new int[n+1];
dp[0]=1;
for(int i=1;i<=m;i++){
for(int j=n;j>=1;j--){
if(ss[i-1]==tt[j-1]){
dp[j]=dp[j-1]+dp[j];
}
}
}
return dp[n];
}
}
28. 实现 strStr()
class Solution {
public int strStr(String haystack, String needle) {
int left=0;
int right=0;
while(left<haystack.length()&&right<needle.length()){
if(haystack.charAt(left)==needle.charAt(right)){
left++;
right++;
}else{
left=left-right+1;
right=0;
}
}
return right==needle.length()?left-needle.length():-1;
}
}
KMP的代码,目前还无法理解,记录下,加油
public class Code01_KMP {
public static int getIndexOf(String s, String m) {
if (s == null || m == null || m.length() < 1 || s.length() < m.length()) {
return -1;
}
char[] str1 = s.toCharArray();
char[] str2 = m.toCharArray();
int i1 = 0;
int i2 = 0;
int[] next = getNextArray(str2);
while (i1 < str1.length && i2 < str2.length) {
if (str1[i1] == str2[i2]) {
i1++;
i2++;
} else if (next[i2] == -1) {
i1++;
} else {
i2 = next[i2];
}
}
return i2 == str2.length ? i1 - i2 : -1;
}
public static int[] getNextArray(char[] ms) {
if (ms.length == 1) {
return new int[] { -1 };
}
int[] next = new int[ms.length];
next[0] = -1;
next[1] = 0;
int i = 2;
int cn = 0;
while (i < next.length) {
if (ms[i - 1] == ms[cn]) {
next[i++] = ++cn;
} else if (cn > 0) {
cn = next[cn];
} else {
next[i++] = 0;
}
}
return next;
}
public static void main(String[] args) {
String str = "abcabcababaccc";
String match = "ababa";
System.out.println(getIndexOf(str, match));
}