5247. 交換字符使得字符串相同
5247. 交換字符使得字符串相同
用戶通過次數583
用戶嘗試次數721
通過次數597
提交次數1363
題目難度Easy
有兩個長度相同的字符串 s1 和 s2,且它們其中 只含有 字符 "x" 和 "y",你需要通過「交換字符」的方式使這兩個字符串相同。
每次「交換字符」的時候,你都可以在兩個字符串中各選一個字符進行交換。
交換隻能發生在兩個不同的字符串之間,絕對不能發生在同一個字符串內部。也就是說,我們可以交換 s1[i] 和 s2[j],但不能交換 s1[i] 和 s1[j]。
最後,請你返回使 s1 和 s2 相同的最小交換次數,如果沒有方法能夠使得這兩個字符串相同,則返回 -1 。
示例 1:
輸入:s1 = "xx", s2 = "yy"
輸出:1
解釋:
交換 s1[0] 和 s2[1],得到 s1 = "yx",s2 = "yx"。
示例 2:
輸入:s1 = "xy", s2 = "yx"
輸出:2
解釋:
交換 s1[0] 和 s2[0],得到 s1 = "yy",s2 = "xx" 。
交換 s1[0] 和 s2[1],得到 s1 = "xy",s2 = "xy" 。
注意,你不能交換 s1[0] 和 s1[1] 使得 s1 變成 "yx",因爲我們只能交換屬於兩個不同字符串的字符。
示例 3:
輸入:s1 = "xx", s2 = "xy"
輸出:-1
示例 4:
輸入:s1 = "xxyyxyxyxx", s2 = "xyyxyxxxyx"
輸出:4
提示:
1 <= s1.length, s2.length <= 1000
s1, s2 只包含 'x' 或 'y'。
這個題是個找規律題。
- 記錄下x-y和y-x的個數,因爲除去相同的x-x,y-y,剩下的都是上圖不相等的。
- 任意兩個x-y或y-x可以經過一次交換變成相同的
- 所以可以經過取模運算可以得到成對的x-y或y-x的個數,也就是變換的次數
- 成對的計算完,最終可能有三種情況。
- x-y和y-x各剩一個——這種變化次數是2
- 各剩0,這種不需要再交換了
- 其他,都是不能交換成功的
public int minimumSwap(String s1, String s2) {
if (s1.length() != s2.length()) {
return -1;
}
int countXY = 0;
int countYX = 0;
for (int i = 0; i < s1.length(); i++) {
if (s1.charAt(i) == 'x' && s2.charAt(i) == 'y') {
countXY++;
} else if (s1.charAt(i) == 'y' && s2.charAt(i) == 'x') {
countYX++;
}
}
int sum = countYX / 2;
countYX = countYX % 2;
sum += countXY / 2;
countXY = countXY % 2;
if (countXY == 1 && countYX == 1) {
return sum + 2;
} else if (countXY == 0 && countYX == 0) {
return sum;
} else {
return -1;
}
}
5248. 統計「優美子數組」
5248. 統計「優美子數組」
用戶通過次數407
用戶嘗試次數605
通過次數415
提交次數1137
題目難度Medium
給你一個整數數組 nums 和一個整數 k。
如果某個子數組中恰好有 k 個奇數數字,我們就認爲這個子數組是「優美子數組」。
請返回這個數組中「優美子數組」的數目。
示例 1:
輸入:nums = [1,1,2,1,1], k = 3
輸出:2
解釋:包含 3 個奇數的子數組是 [1,1,2,1] 和 [1,2,1,1] 。
示例 2:
輸入:nums = [2,4,6], k = 1
輸出:0
解釋:數列中不包含任何奇數,所以不存在優美子數組。
示例 3:
輸入:nums = [2,2,2,1,2,2,1,2,2,2], k = 2
輸出:16
提示:
1 <= nums.length <= 50000
1 <= nums[i] <= 10^5
1 <= k <= nums.length
很簡單,將所有的奇數下標存到list裏面。然後遍歷。
- 對於最左邊的index,計算他與上一個index的距離
- 對於最右邊的index,計算他與下一個index的距離
- 最終結果就是 += 左邊距離 * 右邊距離
前面兩個註釋的代碼都超時了,第一個是暴力循環,第二個是兩重循環的前綴和。
public int numberOfSubarrays(int[] nums, int k) {
/* int count = 0;
int left = -1;
int sum = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] % 2 == 1) {
if (left == -1) {
left = i;
}
count++;
}
if (count == k) {
int l = 1;
int r = 1;
int lefttem = left;
while (lefttem > 0 && nums[--lefttem] % 2 == 0) {
l++;
}
int item = i;
while (item < nums.length - 1 && nums[++item] % 2 == 0) {
r++;
}
sum += l * r;
if (i == nums.length - 1) {
break;
} else {
i = left;
}
left = -1;
count = 0;
}
}
return sum;*/
/* int arr[] = new int[nums.length + 1];
for (int i = 0; i < nums.length; i++) {
if (nums[i] % 2 == 0) {
nums[i] = 0;
} else {
nums[i] = 1;
}
}
arr[0] = 0;
arr[1] = nums[0];
for (int i = 1; i < nums.length + 1; i++) {
arr[i] = arr[i - 1] + nums[i - 1];
}
int sum = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < i; j++) {
if (arr[i] - arr[j] == k) {
sum++;
}
}
}
return sum;*/
int sum = 0;
List<Integer> list = new ArrayList<>();
for (int i = 0; i < nums.length; i++) {
if (nums[i] % 2 == 1) {
list.add(i);
}
}
for (int i = k - 1; i < list.size(); i++) {
int l, r;
int leftIndex = i - k + 1;
if (leftIndex > 0) {
l = list.get(leftIndex) - list.get(leftIndex - 1);
} else {
l = list.get(leftIndex) + 1;
}
if (i < list.size() - 1) {
r = list.get(i + 1) - list.get(i);
} else {
r = nums.length - list.get(i);
}
sum += r * l;
}
return sum;
}
5249. 移除無效的括號
5249. 移除無效的括號
用戶通過次數419
用戶嘗試次數500
通過次數425
提交次數839
題目難度Medium
給你一個由 '('、')' 和小寫字母組成的字符串 s。
你需要從字符串中刪除最少數目的 '(' 或者 ')' (可以刪除任意位置的括號),使得剩下的「括號字符串」有效。
請返回任意一個合法字符串。
有效「括號字符串」應當符合以下 任意一條 要求:
空字符串或只包含小寫字母的字符串
可以被寫作 AB(A 連接 B)的字符串,其中 A 和 B 都是有效「括號字符串」
可以被寫作 (A) 的字符串,其中 A 是一個有效的「括號字符串」
示例 1:
輸入:s = "lee(t(c)o)de)"
輸出:"lee(t(c)o)de"
解釋:"lee(t(co)de)" , "lee(t(c)ode)" 也是一個可行答案。
示例 2:
輸入:s = "a)b(c)d"
輸出:"ab(c)d"
示例 3:
輸入:s = "))(("
輸出:""
解釋:空字符串也是有效的
示例 4:
輸入:s = "(a(b(c)d)"
輸出:"a(b(c)d)"
提示:
1 <= s.length <= 10^5
s[i] 可能是 '('、')' 或英文小寫字母
用棧寫。
-
對於(直接入棧
-
對於)如果棧是空不做操作
-
不是空,那麼棧頂的(則是有效的括號,對應的當前的)也是有效的
最後遍歷就好,
如果是合法的括號就append上、
public String minRemoveToMakeValid(String s) {
Deque<Integer> stack = new LinkedList<>();
boolean[] isValid = new boolean[s.length()];
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(') {
stack.push(i);
} else if (s.charAt(i) == ')') {
if (!stack.isEmpty()) {
isValid[stack.pop()] = true;
isValid[i] = true;
}
}
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
if ((s.charAt(i) == '(' || s.charAt(i) == ')') ) {
if (isValid[i]) {
sb.append(s.charAt(i));
}
} else {
sb.append(s.charAt(i));
}
}
return sb.toString();
}
5250. 檢查「好數組」
5250. 檢查「好數組」
用戶通過次數173
用戶嘗試次數243
通過次數186
提交次數540
題目難度Hard
給你一個正整數數組 nums,你需要從中任選一些子集,然後將子集中每一個數乘以一個 任意整數,並求出他們的和。
假如該和結果爲 1,那麼原數組就是一個「好數組」,則返回 True;否則請返回 False。
示例 1:
輸入:nums = [12,5,7,23]
輸出:true
解釋:挑選數字 5 和 7。
5*3 + 7*(-2) = 1
示例 2:
輸入:nums = [29,6,10]
輸出:true
解釋:挑選數字 29, 6 和 10。
29*1 + 6*(-3) + 10*(-1) = 1
示例 3:
輸入:nums = [3,6]
輸出:false
這個題我不會,但是在羣裏有看到別人在講思路。
這個題的意思就是指,判斷所有的數的最大公約數是不是1。如果是那就是true,不是,那就是false。
public boolean isGoodArray(int[] nums) {
int g = nums[0];
for (int num : nums) {
g = Gcd(g, num);
}
return g == 1;
}
int Gcd(int a, int b) {
while (b != 0) {
int r = b;
b = a % b;
a = r;
}
return a;
}