1005. K 次取反后最大化的數組和
簡單
給你一個整數數組 nums 和一個整數 k ,按以下方法修改該數組:
選擇某個下標 i 并將 nums[i] 替換為 -nums[i] 。
重復這個過程恰好 k 次。可以多次選擇同一個下標 i 。
以這種方式修改數組后,返回數組 可能的最大和 。
class Solution {public int largestSumAfterKNegations(int[] nums, int k) {// 先按絕對值大到小排個序reverseAbsNms(nums);for (int i = 0; i < nums.length; i++) {//從前往后遍歷,遇到負數將其變為正數,同時K--if (nums[i] < 0 && k > 0) { // K > 0也是個很重要的條件nums[i] = -nums[i];k--;}}// 如果K還大于0,那么反復轉變數值最小的元素,將K用完if (k % 2 == 1) nums[nums.length - 1] = -nums[nums.length - 1];int sum = 0;for (int i = 0; i < nums.length; i++) {sum += nums[i];}return sum;}public void reverseAbsNms(int[] nums) {for (int i = 0; i < nums.length - 1; i++) {for (int j = 0; j < nums.length - i - 1; j++) {if (Math.abs(nums[j]) < Math.abs(nums[j + 1])) { // 是j不是i !!!int temp = nums[j];nums[j] = nums[j + 1];nums[j + 1] = temp; }}}}
}
134. 加油站
中等
在一條環路上有 n 個加油站,其中第 i 個加油站有汽油 gas[i] 升。
你有一輛油箱容量無限的的汽車,從第 i 個加油站開往第 i+1 個加油站需要消耗汽油 cost[i] 升。你從其中的一個加油站出發,開始時油箱為空。
給定兩個整數數組 gas 和 cost ,如果你可以按順序繞環路行駛一周,則返回出發時加油站的編號,否則返回 -1 。如果存在解,則 保證 它是 唯一 的。
難點:總油量減去總消耗大于等于零為什么一定可以跑完一圈?i如果無法到j的話,那么i和j之間的點也無法到達j的理論,推不出來就背吧
class Solution {public int canCompleteCircuit(int[] gas, int[] cost) {int n = gas.length;// 考慮從每一個點出發 for (int start = 0; start < n; ) {if (gas[start] < cost[start]) {start++; // 這個點連到下一個點都做不到,換個點繼續試} else {int remain = gas[start] - cost[start];int idx = start + 1;while (idx % n != start) {remain += gas[idx % n] - cost[idx % n];if (remain < 0) {break;}idx++; }if (idx % n == start) {return start;} else {start = idx; // 就是那個i如果無法到j的話,那么i和j之間的點也無法到達j的理論,推不出來就背吧}}}// 任何點都不可以return -1;}
}
135. 分發糖果
困難
n 個孩子站成一排。給你一個整數數組 ratings 表示每個孩子的評分。
你需要按照以下要求,給這些孩子分發糖果:
每個孩子至少分配到 1 個糖果。
相鄰兩個孩子評分更高的孩子會獲得更多的糖果。
請你給每個孩子分發糖果,計算并返回需要準備的 最少糖果數目 。
/*
分兩個階段
1、起點下標1 從左往右,只要 右邊 比 左邊 大,右邊的糖果=左邊 + 1
2、起點下標 ratings.length - 2 從右往左, 只要左邊比右邊大,此時
左邊的糖果應該 取本身的糖果數(符合比它左邊大) 和 右邊糖果數 + 1 二者的最大值,
這樣才符合 它比它左邊的大,也比它右邊大*/
class Solution {public int candy(int[] ratings) {int[] candyNums = new int[ratings.length];Arrays.fill(candyNums, 1);// 從前向后for (int i = 1; i < ratings.length; i++) {// 右比左大if (ratings[i] > ratings[i - 1]) candyNums[i] = candyNums[i - 1] + 1;}// 從后向前 int result = candyNums[ratings.length - 1];for (int i = ratings.length - 2; i >= 0; i--) {// 左比右大if (ratings[i] > ratings[i + 1]) {// 取本身的糖果數(符合比它左邊大) 和 右邊糖果數 + 1 二者的最大值,//這樣才符合 它比它左邊的大,也比它右邊大candyNums[i] = Math.max(candyNums[i], candyNums[i + 1] + 1);}result += candyNums[i];}return result;}
}