LeetCode——第161場周賽


在這裏插入圖片描述

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;
 }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章