这里写目录标题
字符
1.520
class Solution {
public boolean detectCapitalUse(String word) {
int D1=0;
int D2=0;
boolean flg=false;
for (int i = 0; i < word.length(); i++) {
if (word.charAt(0)>= 'A' && word.charAt(0) <='Z' ){
flg=true;
}
if (word.charAt(i) >= 'A' && word.charAt(i) <='Z'){
D1++;
}else {
D2++;
}
}
if (D1 == 1 && D2 == word.length()-1 && flg){
return true;
}else if (D2 == 0 || D1 == 0){
return true;
}
return false;
}
}
回文串的定义
2. 125
class Solution {
public boolean isPalindrome(String s) {
s=s.toLowerCase();
StringBuilder stringBuilder=new StringBuilder();
for (int k = 0; k < s.length(); k++) {
if ((s.charAt(k) >= 'a' && s.charAt(k) <= 'z')||(s.charAt(k) >= '0' && s.charAt(k) <= '9')){
stringBuilder.append(s.charAt(k));
}
}
s=stringBuilder.toString();
int i=0;
int j=s.length()-1;
while (i < j){
if (s.charAt(i) == s.charAt(j)){
i++;
j--;
}else {
return false;
}
}
return true;
}
}
公共前缀
3. 14
class Solution {
public String longestCommonPrefix(String[] strs) {
if (strs == null || strs.length == 0) {
return "";
}
String prefix = strs[0];
int count = strs.length;
for (int i = 1; i < count; i++) {
prefix = longestCommonPrefix(prefix, strs[i]);
if (prefix.length() == 0) {
break;
}
}
return prefix;
}
public String longestCommonPrefix(String str1, String str2) {
int length = Math.min(str1.length(), str2.length());
int index = 0;
while (index < length && str1.charAt(index) == str2.charAt(index)) {
index++;
}
return str1.substring(0, index);
}
}
单词
4. 434
class Solution {
public int countSegments(String s) {
s = s.trim();
if("".equals(s)){
return 0;
}
//按空字符串分割(\s空字符-正则表达式 \s+空字符串 \\s+转义)
String[] ss = s.split("\\s+");
return ss.length;
}
}
5. 58
class Solution {
public int lengthOfLastWord(String s) {
char[] ch=s.toCharArray();
boolean flg=false;
int count=0;
for (int i = ch.length-1; i >=0; i--) {
if (ch[i]==' '&&flg){
break;
}else {
if (ch[i]!=' '){
count++;
flg=true;
}
}
}
return count;
}
}
字符串的反转
6. 344
class Solution {
public void reverseString(char[] s) {
int i=0;
int j=s.length-1;
while (i < j){
char ch=s[i];
s[i]=s[j];
s[j]=ch;
i++;
j--;
}
}
}
7. 541
class Solution {
public String reverseStr(String s, int k) {
int n = s.length();
char[] arr = s.toCharArray();
for (int i = 0; i < n; i += 2 * k) {
reverse(arr, i, Math.min(i + k, n) - 1);
}
return new String(arr);
}
public void reverse(char[] arr, int left, int right) {
while (left < right) {
char temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
left++;
right--;
}
}
}
8. 557
class Solution {
public String reverseWords(String s) {
String[] ret=s.split(" ");
StringBuilder stringBuilder=new StringBuilder();
for (int i = 0; i < ret.length; i++) {
int k=ret[i].length()-1;
while (k >= 0){
stringBuilder.append(ret[i].charAt(k));
k--;
}
if (i != ret.length-1){
stringBuilder.append(" ");
}
}
return stringBuilder.toString();
}
}
9. 151
class Solution {
public String reverseWords(String s) {
s=s.trim();
String[] strings=s.split("\\s+");
String ret=new String();
for (int i = strings.length-1; i >= 0; i--) {
if (i == 0){
ret+=strings[i];
}else {
ret+=strings[i]+" ";
}
}
return ret;
}
}
字符的统计
10. 387
class Solution {
public int firstUniqChar(String s) {
if(s==null)return -1;
int[] arr=new int[26];
for (int i = 0; i < s.length(); i++) {
arr[s.charAt(i)-97]++;
}
for (int i = 0; i < s.length(); i++) {
if (arr[s.charAt(i)-'a']==1){
return i;
}
}
return -1;
}
}
11. 389
class Solution {
public char findTheDifference(String s, String t) {
int[] cnt = new int[26];
for (int i = 0; i < s.length(); ++i) {
char ch = s.charAt(i);
cnt[ch - 'a']++;
}
for (int i = 0; i < t.length(); ++i) {
char ch = t.charAt(i);
cnt[ch - 'a']--;
if (cnt[ch - 'a'] < 0) {
return ch;
}
}
return ' ';
}
}
12. 383
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
if (ransomNote.length() > magazine.length()) {
return false;
}
int[] cnt = new int[26];
for (char c : magazine.toCharArray()) {
cnt[c - 'a']++;
}
for (char c : ransomNote.toCharArray()) {
cnt[c - 'a']--;
if(cnt[c - 'a'] < 0) {
return false;
}
}
return true;
}
}
13. 242
class Solution {
public boolean isAnagram(String s, String t) {
if (s.length() != t.length()){
return false;
}
int[] arr=new int[26];
for (int i = 0; i < s.length(); i++) {
char ch=s.charAt(i);
arr[ch-'a']++;
}
for (int i = 0; i < t.length(); i++) {
char ch=t.charAt(i);
arr[ch - 'a']--;
if ( arr[ch - 'a'] < 0){
return false;
}
}
for (int i:arr) {
if (i != 0){
return false;
}
}
return true;
}
}
14. 49
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
Map<String, List<String>> map = new HashMap<String, List<String>>();
for (String str : strs) {
char[] array = str.toCharArray();
Arrays.sort(array);
String key = new String(array);
List<String> list = map.getOrDefault(key, new ArrayList<String>());
list.add(str);
map.put(key, list);
}
return new ArrayList<List<String>>(map.values());
}
}
15. 451
class Solution {
public String frequencySort(String s) {
char[] cs = s.toCharArray();
Map<Character, Integer> map = new HashMap<>();
for (char c : cs)
map.put(c, map.getOrDefault(c, 0) + 1);
PriorityQueue<int[]> q = new PriorityQueue<>((a,b)->{
return a[1] != b[1] ? b[1] - a[1] : a[0] - b[0];
});
for (char c : map.keySet())
q.add(new int[]{c, map.get(c)});
StringBuilder sb = new StringBuilder();
while (!q.isEmpty()) {
int[] poll = q.poll();
int c = poll[0], k = poll[1];
while (k-- > 0) sb.append((char)(c));
}
return sb.toString();
}
}
16. 423
class Solution {
public String originalDigits(String s) {
Map<Character, Integer> c = new HashMap<Character, Integer>();
for (int i = 0; i < s.length(); ++i) {
char ch = s.charAt(i);
c.put(ch, c.getOrDefault(ch, 0) + 1);
}
int[] cnt = new int[10];
cnt[0] = c.getOrDefault('z', 0);
cnt[2] = c.getOrDefault('w', 0);
cnt[4] = c.getOrDefault('u', 0);
cnt[6] = c.getOrDefault('x', 0);
cnt[8] = c.getOrDefault('g', 0);
cnt[3] = c.getOrDefault('h', 0) - cnt[8];
cnt[5] = c.getOrDefault('f', 0) - cnt[4];
cnt[7] = c.getOrDefault('s', 0) - cnt[6];
cnt[1] = c.getOrDefault('o', 0) - cnt[0] - cnt[2] - cnt[4];
cnt[9] = c.getOrDefault('i', 0) - cnt[5] - cnt[6] - cnt[8];
StringBuffer ans = new StringBuffer();
for (int i = 0; i < 10; ++i) {
for (int j = 0; j < cnt[i]; ++j) {
ans.append((char) (i + '0'));
}
}
return ans.toString();
}
}
17. 657
class Solution {
public boolean judgeCircle(String moves) {
int u=0;
int d=0;
int l=0;
int r=0;
for (int i = 0; i < moves.length(); i++) {
char ch=moves.charAt(i);
if (ch == 'U'){
u++;
}else if (ch == 'D'){
d++;
}else if (ch == 'L'){
l++;
}else {
r++;
}
}
if (d == u && l == r){
return true;
}
return false;
}
}
18. 551
class Solution {
public boolean checkRecord(String s) {
int A=0;
int L=0;
int P=0;
for (int i = 0; i < s.length(); i++) {
char ch=s.charAt(i);
if (ch == 'A'){
A++;
L=0;
if(A >= 2)return false;
}else if (ch == 'L'){
L++;
if(L >= 3)return false;
}else if (ch == 'P'){
P++;
L=0;
}
}
return true;
}
}
19. 696
class Solution {
public int countBinarySubstrings(String s) {
List<Integer> counts = new ArrayList<Integer>();
int ptr = 0, n = s.length();
while (ptr < n) {
char c = s.charAt(ptr);
int count = 0;
while (ptr < n && s.charAt(ptr) == c) {
++ptr;
++count;
}
counts.add(count);
}
int ans = 0;
for (int i = 1; i < counts.size(); ++i) {
ans += Math.min(counts.get(i), counts.get(i - 1));
}
return ans;
}
}
20. 467
在这里插入代码片
数字与字符间的转换
21.412
public List<String> fizzBuzz(int n) {
/*给你一个整数 n ,找出从 1 到 n 各个整数的 Fizz Buzz 表示,并用字符串数组 answer(下标从 1 开始)返回结果,其中:
answer[i] == "FizzBuzz" 如果 i 同时是 3 和 5 的倍数。
answer[i] == "Fizz" 如果 i 是 3 的倍数。
answer[i] == "Buzz" 如果 i 是 5 的倍数。
answer[i] == i (以字符串形式)如果上述条件全不满足。*/
List<String> res = new LinkedList<>();
for(int i =0 ; i < n ; i++){
int k = i+1;
if(k % 3 == 0 && k % 5 == 0){
res.add("FizzBuzz");
}else if(k % 3 == 0){
res.add("Fizz");
}else if( k % 5 == 0){
res.add("Buzz");
}else{
res.add(String.valueOf(k));
}
}
return res;
}
22.506
public String[] findRelativeRanks(int[] score) {
/*给你一个长度为 n 的整数数组 score ,其中 score[i] 是第 i 位运动员在比赛中的得分。所有得分都 互不相同 。
运动员将根据得分 决定名次 ,其中名次第 1 的运动员得分最高,名次第 2 的运动员得分第 2 高,依此类推。运动员的名次决定了他们的获奖情况:
名次第 1 的运动员获金牌 "Gold Medal" 。
名次第 2 的运动员获银牌 "Silver Medal" 。
名次第 3 的运动员获铜牌 "Bronze Medal" 。
从名次第 4 到第 n 的运动员,只能获得他们的名次编号(即,名次第 x 的运动员获得编号 "x")。
使用长度为 n 的数组 answer 返回获奖,其中 answer[i] 是第 i 位运动员的获奖情况。*/
int n = score.length;
String[] desc = {"Gold Medal", "Silver Medal", "Bronze Medal"};
int[][] arr = new int[n][2];
for (int i = 0; i < n; ++i) {
arr[i][0] = score[i];
arr[i][1] = i;
}
Arrays.sort(arr, (a, b) -> b[0] - a[0]);
String[] ans = new String[n];
for (int i = 0; i < n; ++i) {
if (i >= 3) {
ans[arr[i][1]] = Integer.toString(i + 1);
} else {
ans[arr[i][1]] = desc[i];
}
}
return ans;
}
23.539
public int findMinDifference(List<String> timePoints) {
Collections.sort(timePoints);
int ans = Integer.MAX_VALUE;
int t0Minutes = getMinutes(timePoints.get(0));
int preMinutes = t0Minutes;
for (int i = 1; i < timePoints.size(); ++i) {
int minutes = getMinutes(timePoints.get(i));
ans = Math.min(ans, minutes - preMinutes); // 相邻时间的时间差
preMinutes = minutes;
}
ans = Math.min(ans, t0Minutes + 1440 - preMinutes); // 首尾时间的时间差
return ans;
}
public int getMinutes(String t) {
return ((t.charAt(0) - '0') * 10 + (t.charAt(1) - '0')) * 60 + (t.charAt(3) - '0') * 10 + (t.charAt(4) - '0');
}
24.553
解法: 求一个数的最小值,应该怎么求,应该从头除到尾,就是它所在的最小,所以如果我们想让分母变小,分子变大的话,就应该保留第一个数,然后从第二个数从头除到尾.
class Solution {
public String optimalDivision(int[] nums) {
int n = nums.length;
if (n == 1) {
return String.valueOf(nums[0]);
}
if (n == 2) {
return String.valueOf(nums[0]) + "/" + String.valueOf(nums[1]);
}
StringBuffer res = new StringBuffer();
res.append(nums[0]);
res.append("/(");
res.append(nums[1]);
for (int i = 2; i < n; i++) {
res.append("/");
res.append(nums[i]);
}
res.append(")");
return res.toString();
}
}
537
分开俩个数,然后用乘法乘出来转字符串就行
public String complexNumberMultiply(String num1, String num2) {
String[] complex1 = num1.split("\\+|i");
String[] complex2 = num2.split("\\+|i");
int real1 = Integer.parseInt(complex1[0]);
int imag1 = Integer.parseInt(complex1[1]);
int real2 = Integer.parseInt(complex2[0]);
int imag2 = Integer.parseInt(complex2[1]);
return String.format("%d+%di", real1 * real2 - imag1 * imag2, real1 * imag2 + imag1 * real2);
}
592—
640
作者:宫水三叶
链接:https://leetcode.cn/problems/solve-the-equation/solutions/1736347/by-ac_oier-fvee/
class Solution {
public String solveEquation(String s) {
int x = 0, num = 0, n = s.length();
char[] cs = s.toCharArray();
for (int i = 0, op = 1; i < n; ) {
if (cs[i] == '+') {
op = 1; i++;
} else if (cs[i] == '-') {
op = -1; i++;
} else if (cs[i] == '=') {
x *= -1; num *= -1; op = 1; i++;
} else {
int j = i;
while (j < n && cs[j] != '+' && cs[j] != '-' && cs[j] != '=') j++;
if (cs[j - 1] == 'x') x += (i < j - 1 ? Integer.parseInt(s.substring(i, j - 1)) : 1) * op;
else num += Integer.parseInt(s.substring(i, j)) * op;
i = j;
}
}
if (x == 0) return num == 0 ? "Infinite solutions" : "No solution";
else return "x=" + (num / -x);
}
}
38
public String countAndSay(int n) {
String str = "1";
for (int i = 2; i <= n; ++i) {
StringBuilder sb = new StringBuilder();
int start = 0;
int pos = 0;
while (pos < str.length()) {
while (pos < str.length() && str.charAt(pos) == str.charAt(start)) {
pos++;
}
sb.append(Integer.toString(pos - start)).append(str.charAt(start));
start = pos;
}
str = sb.toString();
}
return str;
}
子序列
392
public boolean isSubsequence(String s, String t) {
/*给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。
(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。
进阶:
如果有大量输入的 S,称作 S1, S2, ... , Sk 其中 k >= 10亿,
你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?*/
// 判断是否存在这个字符 , 第二判断字符顺序是不是在了
int fast =0 ,slow = 0;//快慢指针
while (fast < t.length()){
if (slow < s.length() &&s.charAt(slow) == t.charAt(fast)){
slow++;
}
fast++;
}
return slow == s.length();
}
524
class Solution {
public boolean isSubsequence(String s, String t) {
/*给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。
(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。
进阶:
如果有大量输入的 S,称作 S1, S2, ... , Sk 其中 k >= 10亿,
你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?*/
// 判断是否存在这个字符 , 第二判断字符顺序是不是在了
int fast =0 ,slow = 0;//快慢指针
while (fast < t.length()){
if (slow < s.length() &&s.charAt(slow) == t.charAt(fast)){
slow++;
}
fast++;
}
return slow == s.length();
}
public String findLongestWord(String s, List<String> dictionary) {
int fast=0,slow=0;
int len =0,k =0;
for (int i = 0; i < dictionary.size(); i++) {
if (isSubsequence(dictionary.get(i),s)){
if (dictionary.get(i).length() > len){
len = dictionary.get(i).length();
k = i;
}else if (dictionary.get(i).length() == len){
if (dictionary.get(i).compareTo(dictionary.get(k)) < 0){
k = i;
}
}
}
}
if (len == 0)return "";
return dictionary.get(k);
}
}
521
public int findLUSlength(String a, String b) {
/*给你两个字符串 a 和 b,请返回 这两个字符串中 最长的特殊序列 的长度。如果不存在,则返回 -1 。
「最长特殊序列」 定义如下:该序列为 某字符串独有的最长子序列(即不能是其他字符串的子序列) 。
字符串 s 的子序列是在从 s 中删除任意数量的字符后可以获得的字符串。
例如,"abc" 是 "aebdc" 的子序列,因为删除 "aebdc" 中斜体加粗的字符可以得到 "abc" 。
"aebdc" 的子序列还包括 "aebdc" 、 "aeb" 和 "" (空字符串)。*/
if(a.equals(b))
return -1;
return a.length() > b.length() ? a.length() : b.length();
}
522
高精度运算
66
public int[] plusOne(int[] digits) {
for (int i = digits.length - 1; i >= 0; i--) {
if (digits[i] == 9) {
digits[i] = 0;
} else {
digits[i] += 1;
return digits;
}
}
//如果所有位都是进位,则长度+1
digits= new int[digits.length + 1];
digits[0] = 1;
return digits;
}
67
public String addBinary(String a, String b) {
/*给你两个二进制字符串 a 和 b ,以二进制字符串的形式返回它们的和。*/
StringBuilder res = new StringBuilder(); // 返回结果
int i = a.length() - 1; // 标记遍历到 a 的位置
int j = b.length() - 1; // 标记遍历到 b 的位置
int carry = 0; // 进位
while (i >= 0 || j >= 0 || carry != 0) { // a 没遍历完,或 b 没遍历完,或进位不为 0
int digitA = i >= 0 ? a.charAt(i) - '0' : 0; // 当前 a 的取值
int digitB = j >= 0 ? b.charAt(j) - '0' : 0; // 当前 b 的取值
int sum = digitA + digitB + carry; // 当前位置相加的结果
carry = sum >= 2 ? 1 : 0; // 是否有进位
sum = sum >= 2 ? sum - 2 : sum; // 去除进位后留下的数字
res.append(sum); // 把去除进位后留下的数字拼接到结果中
i --; // 遍历到 a 的位置向左移动
j --; // 遍历到 b 的位置向左移动
}
return res.reverse().toString(); // 把结果反转并返回
}
415
定义两个指针 i和 j分别指向 num1 和 num2的末尾,即最低位,同时定义一个变量 add 维护当前是否有进位,然后从末尾到开头逐位相加即可。你可能会想两个数字位数不同怎么处理,这里我们统一在指针当前下标处于负数的时候返回 0,等价于对位数较短的数字进行了补零操作,这样就可以除去两个数字位数不同情况的处理,具体可以看下面的代码。
class Solution {
public String addStrings(String num1, String num2) {
int i = num1.length() - 1, j = num2.length() - 1, add = 0;
StringBuffer ans = new StringBuffer();
while (i >= 0 || j >= 0 || add != 0) {
int x = i >= 0 ? num1.charAt(i) - '0' : 0;
int y = j >= 0 ? num2.charAt(j) - '0' : 0;
int result = x + y + add;
ans.append(result % 10);
add = result / 10;
i--;
j--;
}
// 计算完以后的答案需要翻转过来
ans.reverse();
return ans.toString();
}
}
字符串匹配
28
KMP算法
class Solution {
public int strStr(String haystack, String needle) {
return getIndexOf(haystack,needle);
}
public static int getIndexOf(String s,String m){
if (s == null || m == null || m.length() >s.length() || m.length() < 1){
return -1;
}
char[] str1 = s.toCharArray();
char[] str2 = m.toCharArray();
int i1= 0;
int i2 = 0;
int[] next = getNextArray(str2);//O(M)
while (i1 < str1.length && i2 < str2.length){
//i2 == str2.length的时候代表着,肯定匹配到了
//O(N)
if (str1[i1] == str2[i2]){
//如果相等,继续往后匹配
i1++;
i2++;
}else if (next[i2] == -1){
//如果没有前缀和后缀匹配的,那没办法,只能往后走了
i1++;
}else {
//如果不等,则找前缀和后缀最大的那个
//要验证之前走过的是否有与str2匹配的情况
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;//即代表那个位置的值与i-1的值比
while (i < next.length){
if (ms[i-1] == ms[cn]){
next[i++] = ++cn;
}else if (cn > 0){
//当前跳到cn位置的字符,和i-1位置的对应不上
cn = next[cn];
}else {
//当cn为-1的时候,代表跳到了0下标的位置了
next[i++] = 0;
}
}
return next;
}
}
686
本质还是kmp,先让字符串a 叠加的长度超过字符串b,然后调用kmp即可
class Solution {
public int repeatedStringMatch(String a, String b) {
StringBuilder sb = new StringBuilder();
int ans = 0;
while (sb.length() < b.length() && ++ans > 0) sb.append(a);
sb.append(a);
int idx = strStr(sb.toString(), b);
if (idx == -1) return -1;
return idx + b.length() > a.length() * ans ? ans + 1 : ans;
}
int strStr(String ss, String pp) {
if (pp.isEmpty()) return 0;
// 分别读取原串和匹配串的长度
int n = ss.length(), m = pp.length();
// 原串和匹配串前面都加空格,使其下标从 1 开始
ss = " " + ss;
pp = " " + pp;
char[] s = ss.toCharArray();
char[] p = pp.toCharArray();
// 构建 next 数组,数组长度为匹配串的长度(next 数组是和匹配串相关的)
int[] next = new int[m + 1];
// 构造过程 i = 2,j = 0 开始,i 小于等于匹配串长度 【构造 i 从 2 开始】
for (int i = 2, j = 0; i <= m; i++) {
// 匹配不成功的话,j = next(j)
while (j > 0 && p[i] != p[j + 1]) j = next[j];
// 匹配成功的话,先让 j++
if (p[i] == p[j + 1]) j++;
// 更新 next[i],结束本次循环,i++
next[i] = j;
}
// 匹配过程,i = 1,j = 0 开始,i 小于等于原串长度 【匹配 i 从 1 开始】
for (int i = 1, j = 0; i <= n; i++) {
// 匹配不成功 j = next(j)
while (j > 0 && s[i] != p[j + 1]) j = next[j];
// 匹配成功的话,先让 j++,结束本次循环后 i++
if (s[i] == p[j + 1]) j++;
// 整一段匹配成功,直接返回下标
if (j == m) return i - m;
}
return -1;
}
}
459
解决方法: 枚举一半的字符串长度,来进行匹配
class Solution {
public boolean repeatedSubstringPattern(String s) {
int n = s.length();
for (int i = 1; i * 2 <= n; ++i) {
if (n % i == 0) {
boolean match = true;
for (int j = i; j < n; ++j) {
if (s.charAt(j) != s.charAt(j - i)) {
match = false;
break;
}
}
if (match) {
return true;
}
}
}
return false;
}
}