100352. 交换后字典序最小的字符串
给你一个仅由数字组成的字符串 s
,在最多交换一次 相邻 且具有相同 奇偶性 的数字后,返回可以得到的字典序最小的字符串。
如果两个数字都是奇数或都是偶数,则它们具有相同的奇偶性。例如,5 和 9、2 和 4 奇偶性相同,而 6 和 9 奇偶性不同。
思路
从左到右扫一遍就行,交换的越早越好,因为字典序是从左往右看的
import java.util.Arrays; class Solution { public String getSmallestString(String s) { char[] charArray = s.toCharArray(); for (int i = 0; i < charArray.length - 1; i++) { int now = charArray[i] - '0', nxt = charArray[i + 1] - '0'; if (now % 2 == nxt % 2 && now > nxt) { char tmp = charArray[i]; charArray[i] = charArray[i + 1]; charArray[i + 1] = tmp; break; } } return new String(charArray); } }
100368. 从链表中移除在数组中存在的节点
给你一个整数数组 nums
和一个链表的头节点 head
。从链表中移除所有存在于 nums
中的节点后,返回修改后的链表的头节点。
思路
将nums转成一个set,就能在O(1)的时间内判断当前节点值在不在nums里,然后扫一遍维护指针就行
当然还有一种方法是记录那些没在nums里的节点值,重新做一个链表出来返回
import java.util.HashSet; import java.util.Set; class Solution { public ListNode modifiedList(int[] nums, ListNode head) { if (head == null) return null; Set<Integer> set = new HashSet<>(); for (int num : nums) { set.add(num); } ListNode newHead = head; while (newHead != null && set.contains(newHead.val)) newHead = newHead.next; if (newHead == null) return null; ListNode pre = newHead; while (pre.next != null) { ListNode now = pre.next; if (set.contains(now.val)) { pre.next = findNewNextNode(set, now); if (pre.next != null) pre = pre.next; continue; } pre = now; } return newHead; } private ListNode findNewNextNode(Set<Integer> set, ListNode now) { ListNode ans = now; while (set.contains(ans.val)) { ans = ans.next; if (ans == null) break; } return ans; } }
100361. 切蛋糕的最小总开销 I
有一个 m x n
大小的矩形蛋糕,需要切成 1 x 1
的小块。
给你整数 m
,n
和两个数组:
horizontalCut
的大小为m - 1
,其中horizontalCut[i]
表示沿着水平线i
切蛋糕的开销。verticalCut
的大小为n - 1
,其中verticalCut[j]
表示沿着垂直线j
切蛋糕的开销。
一次操作中,你可以选择任意不是 1 x 1
大小的矩形蛋糕并执行以下操作之一:
- 沿着水平线
i
切开蛋糕,开销为horizontalCut[i]
。 - 沿着垂直线
j
切开蛋糕,开销为verticalCut[j]
。
每次操作后,这块蛋糕都被切成两个独立的小蛋糕。
每次操作的开销都为最开始对应切割线的开销,并且不会改变。
请你返回将蛋糕全部切成 1 x 1
的蛋糕块的 最小 总开销。
思路
当你横着切一刀时,竖着切时都要加一刀,竖着切同理,所以我们想每次切大的花费的边,这样就不会重复切多次。把横边和竖边降序排序,维护两个多切系数,每次选择横边和竖边较大的那边来切,同时维护多切系数,横的切一刀,竖边的多切系数就要+1,反之同理
import java.util.Arrays; class Solution { public static int minimumCost(int m, int n, int[] horizontalCut, int[] verticalCut) { int cos = 0; int horizonNum = 1, verticalNum = 1; reverseOrderQuickSort(horizontalCut, 0, horizontalCut.length - 1); reverseOrderQuickSort(verticalCut, 0, verticalCut.length - 1); int i = 0, j = 0; while (i < horizontalCut.length || j < verticalCut.length) { if (i == horizontalCut.length) { cos += verticalCut[j] * verticalNum; j++; continue; } if (j == verticalCut.length) { cos += horizontalCut[i] * horizonNum; i++; continue; } if (horizontalCut[i] > verticalCut[j]) { cos += horizontalCut[i] * horizonNum; verticalNum++; i++; } else { cos += verticalCut[j] * verticalNum; horizonNum++; j++; } } return cos; } private static void reverseOrderQuickSort(int[] num, int left, int right) { if (left < right) { int i = left, j = right, n = num[left]; while (i < j) { while (i < j && num[j] <= n) j--; if (i < j) num[i++] = num[j]; while (i < j && num[i] > n) i++; if (i < j) num[j--] = num[i]; } num[i] = n; reverseOrderQuickSort(num, left, i - 1); reverseOrderQuickSort(num, i + 1, right); } } }
100367. 切蛋糕的最小总开销 II
题意和刚刚一样,在刚刚的基础上增大n和m的数据量
思路
和第三题是一样的,我的解法tle了,时间复杂度应该是一样的,问题应该是手写的快排没有jdk的速度快,用jdk的api就能AC
import java.util.Arrays; class Solution { public long minimumCost(int m, int n, int[] horizontalCut, int[] verticalCut) { long cos = 0; int horizonNum = 1, verticalNum = 1; Arrays.sort(horizontalCut); Arrays.sort(verticalCut); int i = horizontalCut.length - 1, j = verticalCut.length - 1; while (i >= 0 || j >= 0) { if (j < 0 || i >= 0 && horizontalCut[i] > verticalCut[j]) { cos += (long) horizontalCut[i] * horizonNum; verticalNum++; i--; } else { cos += (long) verticalCut[j] * verticalNum; horizonNum++; j--; } } return cos; } }
标签:周赛,cos,int,++,leetcode,406,num,verticalCut,horizontalCut From: https://www.cnblogs.com/CNLayton/p/18302224