1
22. 括号生成
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例:
输入:n = 3
输出:[
“((()))”,
“(()())”,
“(())()”,
“()(())”,
“()()()”
]
思路:利用递归思想,一个指针记录左边括号数,一个指针记录右边括号数,当右边大于左边时结束,当左边等于n时,若此时字符串长度小于2*n,则补齐)括号,集合中加入该字符返回。
class Solution {
List<String> list = new ArrayList<>();
public List<String> generateParenthesis(int n) {
if(n==0)
return list;
generate(n,0,0,"");
return list;
}
public void generate(int n,int left,int right,String tmp){
if(right>left)
return;
if(n==left){
while(tmp.length()<2*n)
tmp+=")";
list.add(new String(tmp));
return;
}
generate(n,left,right+1,tmp+")");
generate(n,left+1,right,tmp+"(");
}
}
2
3. 无重复字符的最长子串
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:
输入: “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:
输入: “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。
基本思路:利用set集合记录,当查询到重复字符,则跳出,进行下一轮比较
class Solution {
public int lengthOfLongestSubstring(String s) {
Set<Character> set = new HashSet<>();
int max=0;
for(int i=0;i<s.length();i++){
int cnt=0;
for(int j=i;j<s.length();j++){
if(set.contains(s.charAt(j)))
break;
set.add(s.charAt(j));
cnt++;
}
set=new HashSet<>();
if(cnt>max)
max=cnt;
}
return max;
}
}
思路二:维系一个map,每当发现重复字符时,用新的下标代替原来的下标,同时维系着不同的字符最左边的下标left
class Solution {
public int lengthOfLongestSubstring(String s) {
Map<Character,Integer> map = new HashMap<>();
if(s.length()<2)
return s.length();
int left=0;
int max=0;
for(int i=0;i<s.length();i++){
if(map.containsKey(s.charAt(i))){
left=Math.max(left,map.get(s.charAt(i))+1);
}
map.put(s.charAt(i),i);
max=Math.max(max,i-left+1);
}
return max;
}
}
3
6. Z 字形变换
将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 “LEETCODEISHIRING” 行数为 3 时,排列如下:
L C I R
E T O E S I I G
E D H N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“LCIRETOESIIGEDHN”。
请你实现这个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);
示例 1:
输入: s = “LEETCODEISHIRING”, numRows = 3
输出: “LCIRETOESIIGEDHN”
示例 2:
输入: s = “LEETCODEISHIRING”, numRows = 4
输出: “LDREOEIIECIHNTSG”
解释:
L D R
E O E I I
E C I H N
T S G
class Solution {
public String convert(String s, int numRows) {
if(numRows==1)
return s;
int num = numRows*2-2;
int len = s.length();
char[][] arr = new char[numRows][len];
for(int i=0;i<numRows;i++){
for(int j=0;j<len;j++){
arr[i][j]=' ';
}
}
int cnt=0;
int i=0;
int j=0;
while(cnt<s.length()){
while(i<numRows&&cnt<s.length()){
arr[i][j]=s.charAt(cnt);
cnt++;
i++;
}
i--;
i--;
while(i>=0&&cnt<s.length()){
arr[i][++j]=s.charAt(cnt);
cnt++;
i--;
}
i=1;
}
StringBuilder sb = new StringBuilder();
for(int k=0;k<numRows;k++){
for(int m=0;m<=j;m++){
if(arr[k][m]!=' '){
sb.append(arr[k][m]);
}
}
}
return sb.toString();
}
}
4
1016. 子串能表示从 1 到 N 数字的二进制串
给定一个二进制字符串 S(一个仅由若干 ‘0’ 和 ‘1’ 构成的字符串)和一个正整数 N,如果对于从 1 到 N 的每个整数 X,其二进制表示都是 S 的子串,就返回 true,否则返回 false。
示例 1:
输入:S = “0110”, N = 3
输出:true
示例 2:
输入:S = “0110”, N = 4
输出:false
提示:
1 <= S.length <= 1000
1 <= N <= 10^9
思路:求得每个数字的二进制字符串,然后使用string的contains函数判断
class Solution {
public boolean queryString(String S, int N) {
for(int i=1;i<=N;i++){
StringBuilder tmp = new StringBuilder();
int num = i;
while(num>0){
int a = num%2;
num = num/2;
tmp.append(a);
}
String ans= tmp.reverse().toString();
if(!S.contains(ans)){
return false;
}
}
return true;
}
}
5
5. 最长回文子串
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
示例 2:
输入: “cbbd”
输出: “bb”
class Solution {
public String longestPalindrome(String s) {
//分奇偶情况讨论
if(s.length()<2)
return s;
int max=0;
String ans = "";
for(int i=1;i<s.length();i++){
int left=i-1;
int right=i+1;
int cnt=1;
while(left>=0&&right<s.length()){
if(s.charAt(left)==s.charAt(right)){
left--;
right++;
cnt+=2;
}else{
break;
}
}
if(max<cnt){
ans=s.substring(i-(cnt-1)/2,i+(cnt-1)/2+1);
max=cnt;
}
}
for(int i=0;i<s.length();i++){
int left=i;
int right=i+1;
int cnt=0;
while(left>=0&&right<s.length()){
if(s.charAt(left)==s.charAt(right)){
left--;
right++;
cnt+=2;
}else{
break;
}
}
if(max<cnt){
ans=s.substring(i-(cnt/2)+1,i+cnt/2+1);
max=cnt;
}
}
return ans;
}
}
6
1023. 驼峰式匹配
如果我们可以将小写字母插入模式串 pattern 得到待查询项 query,那么待查询项与给定模式串匹配。(我们可以在任何位置插入每个字符,也可以插入 0 个字符。)
给定待查询列表 queries,和模式串 pattern,返回由布尔值组成的答案列表 answer。只有在待查项 queries[i] 与模式串 pattern 匹配时, answer[i] 才为 true,否则为 false。
示例 1:
输入:queries = [“FooBar”,“FooBarTest”,“FootBall”,“FrameBuffer”,“ForceFeedBack”], pattern = “FB”
输出:[true,false,true,true,false]
示例:
“FooBar” 可以这样生成:“F” + “oo” + “B” + “ar”。
“FootBall” 可以这样生成:“F” + “oot” + “B” + “all”.
“FrameBuffer” 可以这样生成:“F” + “rame” + “B” + “uffer”.
思路:利用双指针指向匹配的字符串开始,如果待匹配的字符串大写且与匹配字符串匹配,则都加1,若大写不匹配,则输出false;若为小写,与匹配字符串匹配则都加1,否则自身加1,当其中一个到达末尾结束,此时若待匹配未到末尾但匹配已经到达末尾,再判断待匹配的字符串剩余有无大写,有输出false,若待匹配到达但匹配未到达,也输出false,其余情况输出true
class Solution {
public List<Boolean> camelMatch(String[] queries, String pattern) {
int len =pattern.length();
List<Boolean> ans = new ArrayList<>();
for(String s:queries){
int len2=s.length();
int index1=0;
int index2=0;
boolean flag=true;
while(index1<len2&&index2<len){
if(s.charAt(index1)>='A'&&s.charAt(index1)<='Z'){
if(s.charAt(index1)==pattern.charAt(index2)){
index1++;
index2++;
continue;
}else{
flag=false;
break;
}
}else if(s.charAt(index1)==pattern.charAt(index2)){
index1++;
index2++;
}else {
index1++;
}
}
if(index2<len)
flag=false;
while(index1<len2){
if(s.charAt(index1)>='A'&&s.charAt(index1)<='Z')
flag=false;
index1++;
}
ans.add(flag);
}
return ans;
}
}
7
1324. 竖直打印单词
给你一个字符串 s。请你按照单词在 s 中的出现顺序将它们全部竖直返回。
单词应该以字符串列表的形式返回,必要时用空格补位,但输出尾部的空格需要删除(不允许尾随空格)。
每个单词只能放在一列上,每一列中也只能有一个单词。
示例 1:
输入:s = “HOW ARE YOU”
输出:[“HAY”,“ORO”,“WEU”]
解释:每个单词都应该竖直打印。
“HAY”
“ORO”
“WEU”
示例 2:
输入:s = “TO BE OR NOT TO BE”
输出:[“TBONTB”,“OEROOE”," T"]
解释:题目允许使用空格补位,但不允许输出末尾出现空格。
“TBONTB”
“OEROOE”
" T"
示例 3:
输入:s = “CONTEST IS COMING”
输出:[“CIC”,“OSO”,“N M”,“T I”,“E N”,“S G”,“T”]
class Solution {
public List<String> printVertically(String s) {
List<String> ans = new ArrayList<>();
String[] arr = s.split(" ");
int max=0;
for(int i=0;i<arr.length;i++){
if(arr[i].length()>max)
max=arr[i].length();
}
for(int i=0;i<max;i++){
String tmp="";
for(int j=0;j<arr.length;j++){
if(i>=arr[j].length()){
tmp+=" ";
}else{
tmp+=arr[j].charAt(i);
}
}
int index=0;
for(int k=0;k<tmp.length();k++){
if(tmp.charAt(k)!=' ')
index=k;
}
String ss=tmp.substring(0,index+1);
ans.add(ss);
}
return ans;
}
}
8
1347. 制造字母异位词的最小步骤数
给你两个长度相等的字符串 s 和 t。每一个步骤中,你可以选择将 t 中的 任一字符 替换为 另一个字符。
返回使 t 成为 s 的字母异位词的最小步骤数。
字母异位词 指字母相同,但排列不同(也可能相同)的字符串。
示例 1:
输出:s = “bab”, t = “aba”
输出:1
提示:用 ‘b’ 替换 t 中的第一个 ‘a’,t = “bba” 是 s 的一个字母异位词。
示例 2:
输出:s = “leetcode”, t = “practice”
输出:5
提示:用合适的字符替换 t 中的 ‘p’, ‘r’, ‘a’, ‘i’ 和 ‘c’,使 t 变成 s 的字母异位词。
class Solution {
public int minSteps(String s, String t) {
int[] arr = new int[26];
int[] arr2 = new int[26];
for(int i=0;i<s.length();i++){
arr[s.charAt(i)-'a']++;
arr2[t.charAt(i)-'a']++;
}
int ans=0;
for(int i=0;i<26;i++){
arr[i]-=arr2[i];
if(arr[i]>0)
ans+=arr[i];
}
return ans;
}
}
9
165. 比较版本号
比较两个版本号 version1 和 version2。
如果 version1 > version2 返回 1,如果 version1 < version2 返回 -1, 除此之外返回 0。
你可以假设版本字符串非空,并且只包含数字和 . 字符。
. 字符不代表小数点,而是用于分隔数字序列。
例如,2.5 不是“两个半”,也不是“差一半到三”,而是第二版中的第五个小版本。
你可以假设版本号的每一级的默认修订版号为 0。例如,版本号 3.4 的第一级(大版本)和第二级(小版本)修订号分别为 3 和 4。其第三级和第四级修订号均为 0。
示例 1:
输入: version1 = “0.1”, version2 = “1.1”
输出: -1
示例 2:
输入: version1 = “1.0.1”, version2 = “1”
输出: 1
class Solution {
public int compareVersion(String version1, String version2) {
String[] arr1 = version1.split("\\.");
String[] arr2 = version2.split("\\.");
int[] num1 = new int[arr1.length];
int[] num2 = new int[arr2.length];
for(int i=0;i<arr1.length;i++){
num1[i]=Integer.parseInt(arr1[i]);
}
for(int i=0;i<arr2.length;i++){
num2[i]=Integer.parseInt(arr2[i]);
}
int min = Math.min(arr1.length,arr2.length);
int ans=0;
for(int i=0;i<min;i++){
if(num1[i]>num2[i]){
ans=1;
break;
}
if(num1[i]<num2[i]){
ans=-1;
break;
}
}
if(ans==0){
while(min<arr1.length){
if(num1[min]>0){
ans=1;
break;
}
min++;
}
while(min<arr2.length){
if(num2[min]>0){
ans=-1;
break;
}
min++;
}
}
return ans;
}
}
10
151. 翻转字符串里的单词
给定一个字符串,逐个翻转字符串中的每个单词。
示例 1:
输入: “the sky is blue”
输出: “blue is sky the”
示例 2:
输入: " hello world! "
输出: “world! hello”
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
示例 3:
输入: “a good example”
输出: “example good a”
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
class Solution {
public String reverseWords(String s) {
s=s.trim();
List<String> list = new ArrayList<>();
int index=0;
StringBuilder sb = new StringBuilder();
while(index<s.length()){
if(s.charAt(index)!=' '){
sb.append(s.charAt(index));
}else{
if(sb.length()>0)
list.add(sb.toString());
sb=new StringBuilder();
}
index++;
}
list.add(sb.toString());
StringBuilder ans = new StringBuilder();
for(int i=list.size()-1;i>=0;i--){
ans.append(list.get(i)+" ");
}
return ans.toString().trim();
}
}