코드랜덤녹화 알고리즘 훈련캠프 34일차|1005. K부정 후 배열 합 최대화, 134. 주유소, 135. 사탕 나눠주기

목차

1005. K회 반전 후 최대화된 어레이 합

134. 주유소

135. 사탕 나눠주기


1005. K회 반전 후 최대화된 어레이 합

이 질문은 더 간단합니다.. 욕심부릴 생각은 하지 않으셔도 되고, 본인의 직감으로 아이디어가 떠오르실 거라 생각합니다. 

코드 카프리스

솔루션 아이디어:

해결책은 먼저 배열을 절대값 내림차순으로 정렬한 다음 배열의 음수를 정수로 먼저 반전시키는 것입니다. 또한 마지막과 가장 작은 수를 반전시키는 트릭.남은 k의 수가 홀수이면 마지막 숫자를 한 번만 반전하면됩니다.짝수이면 반전을 취하고 과거를 반전 시키십시오. 반전이 없으므로 처리할 필요가 없습니다. 좋습니다. 마지막으로 질문의 의미에 따라 배열의 숫자를 더하는 것입니다.

class Solution {
    public int largestSumAfterKNegations(int[] nums, int k) {
        int result = 0;
        Stream<Integer> integerNums = Arrays.stream(nums).boxed();// 将数组先转换成一个 Integer类型的stream流
        Integer[] newNums = integerNums.toArray(Integer[]::new);  //将流转换为数组
        Arrays.sort(newNums, (o1,o2)->Math.abs(o2) - Math.abs(o1));  //将新数组按大到小排序,使用比较器排序时,必须是对引用类型的数组进行操作,即必须先将int类型的数组转换成Integer类型的数组。
        

        for(int i = 0; i < newNums.length; i++){ //利用k次机会,先把数组中的绝对值较大的负数尽可能的都取反
            if(newNums[i] < 0 && k > 0){
                newNums[i] *= -1;
                k--;
            }
        }
        if(k % 2 != 0) newNums[newNums.length - 1] *= -1; //如果都把负数取反后还剩余k次,k若为奇数,把绝对值最小的数取反即可,k若为偶数,则不需要处理

        for(Integer element : newNums){ //k次取反后累加数组中的各个元素就是最大化的数组和
            result += element;
        }
        return result;
    }
}

134. 주유소

이 질문은 조금 어렵고 생각하기 쉽지 않으니 방법 2를 숙지하시기를 권장합니다. 

코드 카프리스

솔루션 아이디어:

Ka Ge가 제시한 솔루션은 원을 도는 과정을 시뮬레이션하지 않았지만 한 라운드 동안 어레이를 통과한 후 다음과 같이 생각할 수 있습니다. 1.
총 순 오일 증가가 확실하므로 갈 수 있는지 여부를 판단할 수 있습니다. 한 라운드를 통과한 후 원 주위 순 오일 증가량이 0보다 크거나 같으면 예를 의미하고 그 반대의 경우도 마찬가지입니다 2. 시작점은
이 n개의 주유소에서만 선택할 수 있습니다. 가스 첨자 인덱스 값의 여기서 totalSum이 0보다 작으면 시작 = n + 1이 있을 수 있습니다. , 다음 코드는 실행되어 -1을 반환하고 start의 값을 반환하지 않습니다; totalSum이 0보다 크거나 같으면 start =가 없습니다. n + 1의 경우 맨 위 단어는 start =입니다. n, 즉, 마지막 스테이션에서 시작합니다. 앞쪽의 오일 양의 증가가 너무 적고 n번째 스테이션의 오일 양의 증가가 소비된 오일을 상쇄할 수 있기 때문에 최종 totalSum이 0보다 크거나 같습니다. .

class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        int totalSUm = 0;
        int currentSum = 0;
        int start = 0;
        for(int i = 0; i < gas.length; i++){
            currentSum += gas[i] - cost[i]; //计算每个加油站点的总净增油量,如果是负数则表示不能从出发点加油站到开往到正在遍历的第i个加油站,如果是正数表示到达后剩余的油量,即可以到达
            totalSUm  += gas[i] - cost[i]; //计算一轮即所有站点的净增油量如果是负数,表示不管从哪个点出发都不可能环绕一周
            if(currentSum < 0) {  //前面的每个和累加净增油量与当前的负增油量相加小于0,说明不能走到当前遍历的第i个站点,因此需要换从下一个站点开始
                start = i + 1;    //如果前面的所有正数累加都抵不过当前第i个站点的负增油量,那么从前面的每个正的净增油量站点出发都不可能到达第i个站点,就需要从下一个站点去重新判断了。这里注意如果totalSum小于0的话,此时有可能出现start = n + 1,也就是数组越界,但是总净增油量小于0,下面代码会执行返回-1,不会返回start的值;如果totalSum大于等于0的话,一定不会出现start = n + 1的情况,最顶的话也就是start = n,也就是从最后一个站点出发,因为前面正增油量太小了,加上第n个站点的正增油量才能抵消消耗的油量,使得最后totalSum大于等于0,
                currentSum = 0;   //重新判断时需要将正净增油量累加的初始值置为0
            }
        }
        if(totalSUm < 0 ) return -1; //如果总的净增油量小于0,那么一定不会环绕一周
        return start;
    }
}

135. 사탕 나눠주기

이 문제는 생각을 포함하는데, 즉 한쪽을 처리하고 다른 쪽을 처리하고 싶습니다.양쪽 모두를 생각하지 마십시오.이 아이디어를 나중에 사용할 질문이 있습니다. 

코드 카프리스

솔루션 아이디어:

A> B2이면 왼쪽 규칙에 따라 처리한 후 B2는 A보다 크지 않고 오른쪽 규칙에 따라 처리한 후 A는 B2보다 커야 합니다. 업데이트(더 커짐)해야 하며, 이때 확대된 A는 오른쪽보다 높은 포인트 요구 사항을 충족하고 캔디 포인트의 수는 더 많아집니다.

class Solution {
    public int candy(int[] ratings) {
        int[] candyCount = new int[ratings.length];
        Arrays.fill(candyCount, 1);

        for(int i = 1; i < ratings.length; i++){
            if(ratings[i] > ratings[i - 1]){ //左规则:只判断右边比左边大的情况下,给每个小孩发放的数量,此时从前往后遍历
                candyCount[i] = candyCount[i - 1] + 1;
            }
        }
        for(int i = ratings.length - 2; i >= 0; i--){ //右规则:只判断左边比右边大的情况下,给每个小孩发放的数量,此时从后往前遍历,此时更新糖果数组中数量最大的值,才能满足某个孩子比左右两个孩子分都高时,分得的糖果数量会更多
            if(ratings[i] > ratings[i + 1]){
                candyCount[i] = Math.max(candyCount[i], candyCount[i + 1] + 1);  //更新右规则下的A
            }
        }

        int result = 0;
        for(int element : candyCount){
            result += element;
        }
        return result;
    }
}

Guess you like

Origin blog.csdn.net/tore007/article/details/130893322