2021.12.06 __每日一题__算法

输入一个整数数组和一个整数k,按以下方式修改该数组

1.选择某个下标 i 并将 nums[i] 替换为 -nums[i]

2.重复这个过程恰好 k 次。可以多次选择同一个下标 i 。

以这种方式修改数组后,返回数组可能的最大和 。

输入:nums = [4,2,3], k = 1

输出:5

解释:选择下标 1 ,nums 变为 [4,-2,3] 。

输入:nums = [3,-1,0,2], k = 3

输出:6

输入:nums = [2,-3,-1,5,-4], k = 2

输出:13

输入:nums = 

[-2,5,0,2,-2],

k = 3

输出:11

其中:

1 <= nums.length <= 10000

-100 <= nums[i] <= 100

1 <= k <= 10000

 

package Works;

public class Day06 {
    public static void main(String[] args) {
        int[] arr1 = new int[]{2,-3,-1,5,-4};
        int k1 = 2;
        int sum1 = 0;
        int sum2 = 0;
        System.out.print("arr1 = ");
        for (int i = 0; i < arr1.length; i++) {
            System.out.print(arr1[i] + "  ");
        }
        System.out.println();
        method.method1(arr1,k1);
        for (int i = 0; i < arr1.length; i++) {
            sum1 += arr1[i];
        }
        System.out.println("sum1 = " + sum1);
        System.out.println("**********************");
        int[] arr2 = new int[]{3,-1,0,2};
     int k2 = 3; System.out.print(
"arr2 = "); for (int i = 0; i < arr2.length; i++) { System.out.print(arr2[i] + " "); } method.method2(arr2,k2); for (int i = 0; i < arr2.length; i++) { sum2 += arr2[i]; } System.out.println(); System.out.println("sum2 = " + sum2); } } class method { public static void method1(int[] arr, int k) { //先按从小到大将数组排序 Utils.sort(arr, 0, arr.length - 1); for (int i = 0; i < arr.length; i++) { //k允许的情况下,负变正 if (arr[i] < 0 && k > 0) { arr[i] = -arr[i]; k--; //此时已经将小于零的arr[i]变为正数了,使用continue防止进入下一个if,将其再次变为负数 continue; } if (arr[i] > 0 && k > 0) { if (i == 0) { for (int j = 0; j < k; j++) { arr[i] = -arr[i]; } } //防止角标越界,同时取与零相距最近且绝对值最小的数,最后不管是正还是负都给它,确保最终数组和取最大 if (i > 0) { if (arr[i] < arr[i - 1]) { for (int j = 0; j < k; j++) { arr[i] = -arr[i]; } } else { for (int j = 0; j < k; j++) { arr[i - 1] = -arr[i - 1]; } } } break; } } } public static void method2(int[] arr, int k) { int cnt = 0; //全部取正 for (int i = 0; i < arr.length; i++) { if(arr[i] < 0){ arr[i] = - arr[i]; cnt ++; } } //先按从小到大将数组排序 Utils.sort(arr,0,arr.length - 1); if (cnt <= k){ //k足以满足负变正,最后的正负交给绝对值最小的数,使最终求和取最大 k -= cnt;
//            time 优化
// for (int i = 0; i < k; i++) {
// arr[0] = -arr[0];
// }
if (k % 2 == 1){
arr[0] = -arr[0];
}
 }else { //尽可能去取正 k = cnt - k; for (int i = 0; i < k; i++) { arr[i] = -arr[i]; } } } } class Utils { /** * ****快排**** * * @param arr * @param left * @param right */ public static void sort(int[] arr, int left, int right) { if (left >= right) { return; } int i = left; int j = right; int temp = arr[left]; while (i != j) { /** * 区分先后顺序,从判断右边,再判断左边 */ while (i < j && arr[j] >= temp) { j--; } while (i < j && arr[i] <= temp) { i++; } if (i < j) { int t = arr[i]; arr[i] = arr[j]; arr[j] = t; } } arr[left] = arr[i]; arr[i] = temp; sort(arr, left, i - 1); sort(arr, i + 1, right); } }

 

 

 

posted on 2021-12-06 10:11  小诺er  阅读(63)  评论(0)    收藏  举报