Leetcode Tags(3)String(TODO)
一、Easy 696 Count Binary Substrings
Input: "00110011" Output: 6 Explanation: There are 6 substrings that have equal number of consecutive 1's and 0's: "0011", "01", "1100", "10", "0011", and "01". Input: "10101" Output: 4 Explanation: There are 4 substrings: "10", "01", "10", "01" that have equal number of consecutive 1's and 0's.
解题思路:由于字符串是0和1相互交叉的,因此:
1.将s = "110001111000000"分成四个子字符串:group = {
}11
000
1111
000000
2.如果group[i] = 2, group[i+1]=3,那么两个组合起来,一定有11000或者是00111
3.类似于000111的情况,那么就有‘0’*3+‘1’*3,‘0’*2+‘1’*2,‘0’*1+‘1’*1,一共三种情况,因此如果group[i]和group[j]中的最小长度就是可以构成的个数
解题代码:
(1)(O(N) + O(1)) 注意groups[++t] = 1;和groups[t]++;的表示技巧。
public int countBinarySubstrings(String s) { int[] groups = new int[s.length()]; int t = 0; groups[0] = 1; for (int i = 1; i < s.length(); i++) { if (s.charAt(i-1) != s.charAt(i)) { groups[++t] = 1; } else { groups[t]++; } } int ans = 0; for (int i = 1; i <= t; i++) ans += Math.min(groups[i-1], groups[i]); return ans; }
(2)不用group数组而是直接使用两个int类型的数prev和curr来存储每个部分的长度
class Solution { public int countBinarySubstrings(String s) { int ans = 0, prev = 0, cur = 1; for (int i = 1; i < s.length(); i++) { if (s.charAt(i-1) != s.charAt(i)) { ans += Math.min(prev, cur); prev = cur; cur = 1; } else { cur++; } } return ans + Math.min(prev, cur); } }
二、Easy 686. Repeated String Match
For example, with A = "abcd" and B = "cdabcdab". Return 3, because by repeating A three times (“abcdabcdabcd”),
B is a substring of it; and B is not a substring of A repeated two times ("abcdabcd").
1.解法思路
求出满足A*k(k=1,2,3...n)的子字符串是B的最小的k值。
2.解法代码
时间复杂度O(N∗(N+M))
空间复杂度O(M+N)
需要学习的地方:①使用StringBuilder可以一次性append一个字符串。
②for ( ; sb.length() < B.length(); number++) sb.append(A);注意for循环的这种使用技巧与number++的位置。
③使用sb.indexOf(B) >= 0和sb.append(A).indexOf(B) >= 0结合sb.length() < B.length()条件很方便地判断出结果来。
public int repeatedStringMatch(String A, String B) { int number = 1; StringBuilder sb = new StringBuilder(A); for ( ; sb.length() < B.length(); number++) sb.append(A); if (sb.indexOf(B) >= 0) return number; if (sb.append(A).indexOf(B) >= 0) return number+1; return -1; }
三、680. Valid Palindrome II
Given a non-empty string s, you may delete at most one character. Judge whether you can make it a palindrome.
1.正常算法Brute Force [Time Limit Exceeded]
public boolean validPalindrome(String s) { for (int i = 0; i < s.length(); i++) { StringBuilder sb = new StringBuilder(s.substring(0, i).concat(s.substring(i+1))); String result = sb.toString(); if (result.equals(sb.reverse().toString())) return true; } return false; } 或者 public boolean isPalindrome(CharSequence s) { for (int i = 0; i < s.length() / 2; i++) { if (s.charAt(i) != s.charAt(s.length() - 1 - i)) { return false; } } return true; } public boolean validPalindrome(String s) { StringBuilder sb = new StringBuilder(s); for (int i = 0; i < s.length(); i++) { char c = sb.charAt(i); sb.deleteCharAt(i); if (isPalindrome(sb)) return true; sb.insert(i, c); } return isPalindrome(s); }
2.贪心算法Greedy[Accepted](TODO)
四、67. Add Binary
Input: a = "1010", b = "1011"
Output: "10101"
1.传统方法
public String addBinary(String a, String b) { String longStr = (a.length() > b.length()) ? a : b; String shortStr = (a.length() > b.length()) ? b : a; StringBuilder sb = new StringBuilder(); boolean isCarry = false; for (int i = shortStr.length()-1; i >= 0; i--) { if (isCarry) { if ((longStr.charAt(longStr.length()-shortStr.length()+i) == '0' && shortStr.charAt(i) == '0')) { sb.append('1'); isCarry = false; } else if (longStr.charAt(longStr.length()-shortStr.length()+i) == '0' && shortStr.charAt(i) == '1') { sb.append('0'); isCarry = true; } else if (longStr.charAt(longStr.length()-shortStr.length()+i) == '1' && shortStr.charAt(i) == '0') { sb.append('0'); isCarry = true; } else { sb.append('1'); isCarry = true; } } else { if ((longStr.charAt(longStr.length()-shortStr.length()+i) == '0' && shortStr.charAt(i) == '0')) { sb.append('0'); } else if (longStr.charAt(longStr.length()-shortStr.length()+i) == '0' && shortStr.charAt(i) == '1') { sb.append('1'); } else if (longStr.charAt(longStr.length()-shortStr.length()+i) == '1' && shortStr.charAt(i) == '0') { sb.append('1'); } else { sb.append('0'); isCarry = true; } } } for (int i = longStr.length() - shortStr.length() - 1; i >= 0; i--) { if (isCarry) { if (longStr.charAt(i) == '1') { sb.append('0'); isCarry = true; } else { sb.append('1'); isCarry = false; } } else { sb.append(longStr.charAt(i)); } } if (isCarry) sb.append('1'); return sb.reverse().toString(); }
2.非传统数学方法(TODO)(或者是使用堆栈)
public String addBinary(String a, String b) { StringBuilder sb = new StringBuilder(); int i = a.length() - 1, j = b.length() -1, carry = 0; while (i >= 0 || j >= 0) { int sum = carry; if (j >= 0) sum += b.charAt(j--) - '0'; if (i >= 0) sum += a.charAt(i--) - '0'; sb.append(sum % 2); carry = sum / 2; } if (carry != 0) sb.append(carry); return sb.reverse().toString(); }
五、