LeetCode-740-删除并获得点数

题目描述

在这里插入图片描述

错误代码

    public static int deleteAndEarn(int[] nums) {
    	int ans=0;
    	//首先给数组排序
    	Arrays.sort(nums);
    	//存进map里吧
    	HashMap<Integer, Integer> m1 = new HashMap<Integer, Integer>();
    	for(int i=0;i<nums.length;i++) {
    		if(m1.containsKey(nums[i])) m1.put(nums[i], m1.get(nums[i])+1);
    		else m1.put(nums[i], 1);
    	}
    	while(!m1.isEmpty()) {
    		//如果m1里面只有一个数字了
    		if(m1.size()==1) {
        		for (Integer key : m1.keySet()) {
        			ans+=key*m1.get(key);
        			m1.remove(key);
        		}
        		return ans;
    		}
    		//如果m1里面只有两个数字了
    		if(m1.size()==2) {
    			//判断是否相差为1
    			int firstkey=-1;
    			boolean flag=false;
        		for (Integer key : m1.keySet()) {
        			if(firstkey==-1) firstkey = key;
        			else {
        				if(Math.abs(key-firstkey)==1) {
        					if(key*m1.get(key)>firstkey*m1.get(firstkey)) ans+=key*m1.get(key);
        					else ans+=firstkey*m1.get(firstkey);
        				}else{
        					ans+=key*m1.get(key);
        					ans+=firstkey*m1.get(firstkey);
        				}
        				return ans;
        			}
        		}
    		}
    		//找到当前的最大和次大和第三大
    		int Fmax = -1;
    		int Smax = -1;
    		int Tmax = -1;

    		for (Integer key : m1.keySet()) {
    			if(key>Fmax) {
    				Tmax = Smax;
    				Smax = Fmax;
    				Fmax=key;
    				continue;
    			}
    			if(key>Smax && key<Fmax) {
    				Tmax = Smax;
    				Smax = key;
    				continue;
    			}
    			if(key>Tmax) {
    				Tmax = key;
    				continue;
    			}
    		}
    		//如果当前的最大和次大相差的数量大于或等于2 直接取出所有最大的
    		if(Fmax-Smax>=2) {
    			ans+=Fmax*m1.get(Fmax);
    			m1.remove(Fmax);
    		}
    		//如果当前最大和次大只相差1 那么必定要删去一个
    		else {
    			//将最大的点数+第三大的点数同第二大的点数相比 哪个更大 删去哪个
    			int temp1 = Fmax*m1.get(Fmax)+Tmax*m1.get(Tmax);
    			int temp2 = Smax*m1.get(Smax);
    			if(temp1>temp2) { //此时删去最大的点数
    				ans+=Fmax*m1.get(Fmax);
        			m1.remove(Fmax);
        			m1.remove(Smax);
    			}else { //此时删去第二大的点数
    				ans+=Smax*m1.get(Smax);
    				m1.remove(Smax-1);
    				m1.remove(Fmax);
    				m1.remove(Smax);
    			}
    			
    		}
    	}
    	return ans;
    }

正确思路

  1. 我怎么感觉又是动态规划…
  2. 原来是之前做的打家劫舍的马甲版…
  3. 定义状态 dp[i] 表示遍历到数字 i 时能获得的最多点数。
  4. 状态转移方程如下:dp[i] = max( dp[i - 2] + sum[i], dp[i - 1])
  5. 即要不然选择最中间那个 要不然选择左边和右边那个

代码

public int deleteAndEarn(int[] nums) {
 	// 构建 sum 数组,即 数字 * 个数,作为 [打家劫舍] 问题的入参
    int max = Arrays.stream(nums).max().getAsInt();
    int[] sum = new int[max + 1];
    for (int x : nums) {
        sum[x] += x;
    }
    return rob(sum);
}

// 打家劫舍代码
public int rob(int[] sum) {
    int n = sum.length;
    int[] dp = new int[n];
    dp[0] = sum[0];
    dp[1] = Math.max(sum[0], sum[1]);
    for (int i = 2; i < n; i++) {
        dp[i] = Math.max(dp[i - 2] + sum[i], dp[i - 1]);
    }
    return dp[n - 1];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值