Amber-Leedcode-Java - 代码随想录打卡第30-37天-贪心算法汇总

前面的比较简单,已经写完 

45. 跳跃游戏 II

很神奇,在顺好思路再写之后很快就写出来了,这个要点在于范围和最大值之间的取舍,在第一个取值的范围内找最大值,如果找到最大值了,就回到该值,然后测试该最大值是否触及边界

class Solution {
    public int jump(int[] nums) {
        int max = nums[0];
        int number = 0;
        int max_loc = 0;
        if (nums.length <= 1){
            return 0;
        }
        for (int i = 0;i < nums.length;i++){
            int tmp_max = max;
            int j = i;
            if (max >= nums.length - 1){
                number++;
                return number;
            }
            while (j <= tmp_max){
                if (nums[j] + j > max){
                    max = nums[j] + j;
                    max_loc = j;
                }
                j++;
            }
            if (max != tmp_max){
                number++;
                i = max_loc;
            }else{
                number++;
            }
        }
        return number;
    }
}

1005. K 次取反后最大化的数组和

我的天这个题第一次自己写的特别费劲,,,不知道为什么,,意外的情况太多了 ,去看看有没有什么通用解法。。

class Solution {
    int sum(int[] nums,int k){
        int sum = 0;
        for (int i = 0;i < nums.length;i++){
            if (i <= k){
                nums[i] = -nums[i];
            }
            sum = sum + nums[i];
        }
        return sum;
    }

    public int largestSumAfterKNegations(int[] nums, int k) {
        Arrays.sort(nums);
        int sum = 0;
        while (k > nums.length){
            if (k > 4){
                k = k%4;
            }else if (k == 4){
                k = 2;
            }
        }
        if (nums[k-1] <= 0){
            return sum(nums,k-1);
        }else{
            int i = 0;
            for (i = 0; i < k;i++){
                if (nums[i] > 0){
                    break;
                }
            }
            if (i == 0){
                k = k % 2;
                return sum(nums,k - 1);
            }else{
                i = i - 1;
            if ((k - i - 1) == 0 || (k - i - 1)%2 == 0){
                return sum(nums,i);
            }else{
                if (Math.abs(nums[i]) < nums[i+1]){
                    return sum(nums,i-1);
                }else{
                    return sum(nums,i) - nums[i+1] - nums[i+1];
                }
            }
            }
        }
    }
}

果然有更简单的。

class Solution {
    public int largestSumAfterKNegations(int[] nums, int K) {
    	// 将数组按照绝对值大小从大到小排序,注意要按照绝对值的大小
	nums = IntStream.of(nums)
		     .boxed()
		     .sorted((o1, o2) -> Math.abs(o2) - Math.abs(o1))
		     .mapToInt(Integer::intValue).toArray();
	int len = nums.length;	    
	for (int i = 0; i < len; i++) {
	    //从前向后遍历,遇到负数将其变为正数,同时K--
	    if (nums[i] < 0 && K > 0) {
	    	nums[i] = -nums[i];
	    	K--;
	    }
	}
	// 如果K还大于0,那么反复转变数值最小的元素,将K用完

	if (K % 2 == 1) nums[len - 1] = -nums[len - 1];
	return Arrays.stream(nums).sum();

    }
}

134. 加油站

很神奇 凭直觉做出来了,,,感觉如果cost小于等于gas的话,一定是有答案的,并且找到diff最大的地方出发就好了。/。。。。

class Solution {

    public int canCompleteCircuit(int[] gas, int[] cost) {
        int sum_gas = 0;
        int sum_cost = 0;
        int num_gas = 0;
        int max_diff = 0;
        for (int i = 0;i < gas.length;i++){
            sum_gas = sum_gas + gas[i];
            sum_cost = sum_cost + cost[i];
        }
        if (sum_cost > sum_gas){
            return -1;
        }
        for (int i = 0;i < gas.length;i++){
            int diff = sum_gas - sum_cost;
            if (diff > max_diff){
                max_diff = diff;
                num_gas = i;
            }
            sum_cost = sum_cost - cost[i];
            sum_gas = sum_gas - gas[i];
        }
        return num_gas;
    }
}

135. 分发糖果

困难题,跳过,,,

860. 柠檬水找零

不难,想清楚条件判断就好了。

class Solution {
    public boolean lemonadeChange(int[] bills) {
        int count_five = 0;
        int count_ten = 0;
        int count_20 = 0;

        for (int i = 0; i < bills.length; i++){
            if (bills[i] == 5){
                count_five++;
            }else if (bills[i] == 10){
                if (count_five == 0){
                    return false;
                }else{
                    count_five--;
                    count_ten++;
                }
            }else if (bills[i] == 20){
              if (count_ten >= 1){
                  if (count_five >= 1){
                      count_20++;
                      count_five--;
                      count_ten--;
                  }else{
                      return false;
                  }
              }else if (count_five < 3){
                  return false;
              }else if (count_five >= 3){
                  count_five = count_five -3;
                  count_20++;
              }
            }
        }
        return true;

    }
}

406. 根据身高重建队列

没有什么思路,抄的别人的代码,太精妙了

class Solution {
    public int[][] reconstructQueue(int[][] people) {
        // 身高从大到小排(身高相同k小的站前面)
        Arrays.sort(people, (a, b) -> {
            if (a[0] == b[0]) return a[1] - b[1];   // a - b 是升序排列,故在a[0] == b[0]的狀況下,會根據k值升序排列
            return b[0] - a[0];   //b - a 是降序排列,在a[0] != b[0],的狀況會根據h值降序排列
        });

        LinkedList<int[]> que = new LinkedList<>();

        for (int[] p : people) {
            que.add(p[1],p);   //Linkedlist.add(index, value),會將value插入到指定index裡。
        }

        return que.toArray(new int[people.length][]);
    }
}

452. 用最少数量的箭引爆气球

这里要解决溢出的问题

不用管left也可以,因为已经排序了

class Solution {
    public int findMinArrowShots(int[][] points) {
        // Arrays.sort(points, (a, b) -> {
        //     if (a[0] == b[0]) return a[1] - b[1];   
        //     return a[0] - b[0];   
        // });
        //为了解决溢出问题
        Arrays.sort(points, (a, b) -> {
    if (a[0] == b[0]) return Integer.compare(a[1], b[1]);
    return Integer.compare(a[0], b[0]);
});
        int count = 1;
        int right = points[0][1];
        int left = points[0][0];
        for (int i = 1;i < points.length;i++){
            if (points[i][1] < left || points[i][0] > right){
                count++;
                left = points[i][0];
                right = points[i][1];
            }else {
                left = Math.max(left,points[i][0]);
                right= Math.min(right,points[i][1]);
            }
        }
        return count;

    }
}

435. 无重叠区间

累了 休息吧。。day36

这个勉强写出来了,记得要改为最小的right,而不是最大的

763. 划分字母区间

我感觉挺难的,主要是很难想到,可以再做一遍

56. 合并区间

较为简单,基本上秒杀,但是要记住最后的类型转换以及添加最后一个数组

class Solution {
    public int[][] merge(int[][] intervals) {
         Arrays.sort(intervals, (a, b) -> {
    if (a[0] == b[0]) return Integer.compare(a[1], b[1]);
    return Integer.compare(a[0], b[0]);
});
    ArrayList<int[]> result = new ArrayList<>();
    int right = intervals[0][1];
    int left = intervals[0][0];
    for (int i = 1;i < intervals.length;i++){
        if (intervals[i][0] <= right){
            right = Math.max(right,intervals[i][1]);
        }else{
            int[] tmp = {left,right};
            result.add(tmp);
            left = intervals[i][0];
            right = intervals[i][1];
        }
    }
    result.add(new int[]{left, right});
    return result.toArray(new int[result.size()][2]);
    }
}

738. 单调递增的数字

这个题做了好久,吐了,还是不太明白

 968.监控二叉树 (可以跳过)

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个Java代码示例,可以将日期格式转换为"yyyy-MM-dd HH:mm:ss"格式: ```java String format = "yyyy-MM-dd HH:mm:ss"; SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format); String currentTime = simpleDateFormat.format(new Date()); System.out.println(currentTime); ``` 这段代码使用了`SimpleDateFormat`类来定义日期格式,并将当前日期转换为指定格式的字符串。输出结果将是形如"2022-06-06 16:02:31"的字符串。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [JAVA - 时间格式 yyyy-MM-dd HH:mm:ss](https://blog.csdn.net/qq_37978224/article/details/127690663)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [java 时间格式“yyyyMMddHHmmssSSSSSS”的解释](https://blog.csdn.net/Amber_1/article/details/125148962)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [js将日期格式转换为YYYY-MM-DD HH:MM:SS](https://download.csdn.net/download/weixin_38713039/12923244)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值