当前位置: 代码迷 >> 综合 >> 每日一题(day3)
  详细解决方案

每日一题(day3)

热度:90   发布时间:2023-11-22 13:04:44.0

文章目录

  • 前言
  • LeetCode 198. 打家劫舍
  • LeetCode 213. 打家劫舍 II
  • LeetCode 740. 删除并获得点数

前言

?你好,我是辰chen,一个正在考研途中的 s o p h o m o r e sophomore sophomore d o g dog dog?
?目前每日一题主要来自于 leetcode,当然也可能来自洛谷或其他刷题平台,每日一题专栏地址:每日一题
?欢迎大家的关注,我的博客主要关注于考研408以及AIoT的内容

? 每日一题我会给出两种代码, C C C版以及 P y t h o n Python Python版,刷题的目的是为了考研的算法题以及机试(或手写代码)
?这也是为什么不用 C + + C++ C++ 而用 C C C P y t h o n Python Python版代码是为了提高语言熟练度(以后开发大概率用的是 P y t h o n Python Python
? 坚持打卡!踏踏实实走好每一步

以下的几个专栏是本人比较满意的专栏(大部分专栏仍在持续更新),欢迎大家的关注:

?ACM-ICPC算法汇总【基础篇】
?ACM-ICPC算法汇总【提高篇】
?AIoT(人工智能+物联网)
?考研
?CSP认证考试历年题解

?每日一句之前欠时间的债太多,得还。

大家做完可以在评论区打卡留言??,形成良好的学习氛围,一起进步!

LeetCode 198. 打家劫舍

题目描述:

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

示例 1:

输入:[1,2,3,1]
输出:4
解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。偷窃到的最高金额 = 1 + 3 = 4 。

示例 2:

输入:[2,7,9,3,1]
输出:12
解释:偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。偷窃到的最高金额 = 2 + 9 + 1 = 12 。

提示:
1 < = n u m s . l e n g t h < = 100 1 <= nums.length <= 100 1<=nums.length<=100
0 < = n u m s [ i ] < = 400 0 <= nums[i] <= 400 0<=nums[i]<=400

C版AC代码:

int rob(int* nums, int numsSize){
    if (numsSize == 1) return nums[0];else if (numsSize == 2) return fmax(nums[0], nums[1]);else{
    int b = nums[0], a = fmax(nums[0], nums[1]);for (int i = 2; i < numsSize; i ++ ){
    int t = fmax(a, b + nums[i]);b = a;a = t;}return a;}
}

Python版AC代码:

class Solution:def rob(self, nums: List[int]) -> int:l = len(nums)if l == 1:return nums[0]elif l == 2:return max(nums[0], nums[1])else:b, c = max(nums[0], nums[1]), nums[0]# a,b,c分别代表f[i], f[i-1], f[i-2]for i in range(2, l):a = max(b, c + nums[i])c, b = b, areturn a

LeetCode 213. 打家劫舍 II

题目描述:

你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警 。

给定一个代表每个房屋存放金额的非负整数数组,计算你 在不触动警报装置的情况下 ,今晚能够偷窃到的最高金额。

示例 1:

输入:nums = [2,3,2]
输出:3
解释:你不能先偷窃 1 号房屋(金额 = 2),然后偷窃 3 号房屋(金额 = 2), 因为他们是相邻的。

示例 2:

输入:nums = [1,2,3,1]
输出:4
解释:你可以先偷窃 1 号房屋(金额 = 1),然后偷窃 3 号房屋(金额 = 3)。偷窃到的最高金额 = 1 + 3 = 4 。

示例 3:

输入:nums = [1,2,3]
输出:3

提示:
1 < = n u m s . l e n g t h < = 100 1 <= nums.length <= 100 1<=nums.length<=100
0 < = n u m s [ i ] < = 1000 0 <= nums[i] <= 1000 0<=nums[i]<=1000

C版AC代码:

int rob(int* nums, int numsSize){
    if (numsSize == 1) return nums[0];else if (numsSize == 2) return fmax(nums[0], nums[1]);else{
    // 从第一个房子到倒数第二个房子做动态规划int b = nums[0], a = nums[0];for (int i = 2; i < numsSize - 1; i ++ ){
    int t = fmax(a, b + nums[i]);b = a;a = t;}int res = a;// 从第二个房子到最后一个房子做动态规划b = 0, a = nums[1];for (int i = 2; i < numsSize; i ++ ){
    int t = fmax(a, b + nums[i]);b = a;a = t;}res = fmax(res, a);return res;}
}

Python版AC代码:

class Solution:def rob(self, nums: List[int]) -> int:l = len(nums)if l == 1: return nums[0]elif l == 2:return max(nums[0], nums[1])else:# 从第一个房子到倒数第二个房子a, b = nums[0], nums[0]for i in range(2, l - 1):t = max(a, b + nums[i])b, a = a, tres = a# 从第二个房子到最后一个房子a, b = nums[1], 0for i in range(2, l):t = max(a, b + nums[i])b, a = a, tres = max(res, a)return res

LeetCode 740. 删除并获得点数

题目描述:

给你一个整数数组 n u m s nums nums ,你可以对它进行一些操作。

每次操作中,选择任意一个 n u m s [ i ] nums[i] nums[i] ,删除它并获得 n u m s [ i ] nums[i] nums[i] 的点数。之后,你必须删除 所有 等于 n u m s [ i ] ? 1 nums[i] - 1 nums[i]?1 n u m s [ i ] + 1 nums[i] + 1 nums[i]+1 的元素。

开始你拥有 0 0 0 个点数。返回你能通过这些操作获得的最大点数。

示例 1:

输入:nums = [3,4,2]
输出:6
解释:
删除 4 获得 4 个点数,因此 3 也被删除。
之后,删除 2 获得 2 个点数。总共获得 6 个点数。

示例 2:

输入:nums = [2,2,3,3,3,4]
输出:9
解释:
删除 3 获得 3 个点数,接着要删除两个 2 和 4 。
之后,再次删除 3 获得 3 个点数,再次删除 3 获得 3 个点数。
总共获得 9 个点数。

提示:
1 < = n u m s . l e n g t h < = 2 ? 1 0 4 1 <= nums.length <= 2 * 10^4 1<=nums.length<=2?104
1 < = n u m s [ i ] < = 1 0 4 1 <= nums[i] <= 10^4 1<=nums[i]<=104

题目分析: 其实和 打家劫舍 是一模一样的,都是在选择了 i i i 后不可以选择 i ? 1 i-1 i?1 i + 1 i+1 i+1

C版AC代码:

int deleteAndEarn(int* nums, int numsSize){
    int n = 0;for (int i = 0; i < numsSize; i ++ ){
    n = fmax(n, nums[i]);}int f[n + 1];memset(f, 0, sizeof f);for (int i = 0; i < numsSize; i ++ ){
    f[nums[i]] += nums[i];}int b = f[0], a = fmax(f[0], f[1]);for (int i = 2; i <= n; i ++ ){
    int t = fmax(b + f[i], a);b = a;a = t;}return a;
}

Python版AC代码:

class Solution:def deleteAndEarn(self, nums: List[int]) -> int:l = max(nums)f = [0] * (l + 10)for val in nums:f[val] += valb, a = f[0], max(f[0], f[1])for i in range(2, l + 1):b, a = a, max(a, b + f[i])return a