1540. K 次操作转变字符串
class Solution { public boolean canConvertString(String s, String t, int k) { if(s.length() != t.length()) return false; int n = s.length(); int[] arr = new int[26]; int count = 0; for(int i = 0; i < n; i++) { if(s.charAt(i) != t.charAt(i)) { int num = (t.charAt(i) - s.charAt(i) + 26) % 26; arr[num]++; count++; } } for(int i = k; i >= 1; i--) { if(arr[i%26] != 0) { arr[i%26]--; if(--count == 0) return true; } } return count == 0; } }
1541. 平衡括号字符串的最少插入次数
class Solution { public int minInsertions(String s) { int n = s.length(); char[] arr = s.toCharArray(); int left = 0, right = 0, res = 0; for(int i = n - 1; i >= 0; i--) { if(arr[i] == '(') { left++; } else { right++; } while(left > 0 && right >= 0) { if(right >= 2) { right -= 2; if(arr[i] == '(' && right % 2 != 0) { right++; res++; } } else { res += 2 - right; right = 0; } left -= 1; } } return res + ((right&1) == 0 ? right / 2 : (right + 1) / 2 + 1); } }
1542. 找出最长的超赞子字符串
分析:
首先,一个字符串可以重新排序得到一个回文字符串的充要条件是:对字符计数,出现奇数次的字符个数小于等于1。
由此我们可以发现:我们没有必要知道这个数字到底出现了几次,我们只需要关心它到底是出现了奇数次还是偶数次。我们用 0,1 来表示出现了 偶数/奇数 次,由于需要统计的字符只有 0-9十个数字,因此我们只需要一个十位的二进制数 status 即可表示当前所有字符出现次数的奇偶状态,即第i位表示数字 ii 出现次数的奇偶性。 假设当前遇到的数字是 i ,那么更新它的状态就是 status ^= (1 << i) ,因为根据异或的特性,相同为0,不同为1,0异或任何数还是等于那个数,
所以相当于我们只对第 ii 位进行了修改,改变对应二进制位的状态。
我们遍历字符串维护这样一个 status,采用数组标记的思想,pre[status] 表示 status 出现的最早位置(对每一个出现过的状态进行标记)。
满足超赞字符串的条件:
再一次遇到之前已经出现过的 status,说明所有数字都出现了偶数次。(因为每一位二进制位的奇偶性都相同的话,不论都是1还是0,奇-奇=偶-偶=偶,都代表这些字符在中间这一段出现了偶数次,该超赞字符串的长度为 当前位置i - 最早出现的位置pre[status]当前位置i−最早出现的位置pre[status])
与之前出现过的 status 只有一个二进制位不同,说明这个不同的二进制位出现了奇数次 (奇-偶=偶-奇=奇),其余的二进制位出现了偶数次,仍然满足回文字符串的条件。针对这种情况,我们只需要从 0-9 枚举二进制位,然后看之前是否出现过即可,同时维护答案。
class Solution { public int longestAwesome(String s) { int n = s.length(); int status = 0, res = 1; char[] arr = s.toCharArray(); int[] pos = new int[1 << 10]; Arrays.fill(pos,-2); pos[0] = -1; for(int i = 0; i < n; i++) { status ^= 1 << (arr[i] - '0'); if(pos[status] != -2) { res = Math.max(res,i-pos[status]); } else { pos[status] = i; } for(int j = 0; j < 10; j++) { int state = status ^ (1 << j); if(pos[state] != -2) { res = Math.max(res, i - pos[state]); } } } return res; } }