数组-leetcode 414. Third Maximum Number

本文介绍了一种高效算法来解决寻找数组中第三大数值的问题。通过遍历数组并逐步更新最大、次大及第三大的数值,最终找到答案。这种方法的时间复杂度为O(N),空间复杂度为O(1)。

原题链接:Third Maximum Number


分析:找出第三大的数,这是找出第K大的数这道题的一个简易版,当然可以使用找第K大的数的做法(快排,partition,O(N))。这里我们使用的是简单的找最大值的方法,找出第一个的数,找出第二大的数,找出第三大的数,就是结果。


题解:

public class Solution {
    public int thirdMax(int[] nums) {
        /*
            Time Complexity:O(N)
            Space Complexity:O(1)
        */
        int f=nums[0],s=f,t=s;
		boolean flag=false;
		boolean exist=false;
        
		for(int i=0;i<nums.length;i++){
			if(nums[i]>f)f=nums[i];
		}
		for(int i=0;i<nums.length;i++){
			if(nums[i]==f)continue;
			if(!flag){
				s=nums[i];
				flag=true;
			}
			if(nums[i]>s)s=nums[i];
		}
        
		flag=false;	
		for(int i=0;i<nums.length;i++){
			if(nums[i]==f || nums[i]==s)continue;
			if(!flag){
				t=nums[i];
				flag=true;
				exist=true;
			}
			if(nums[i]>t)t=nums[i];
		}
        
		return exist?t:f;
    }
}


B. Array Recoloring time limit per test2 seconds memory limit per test256 megabytes You are given an integer array a of size n . Initially, all elements of the array are colored red. You have to choose exactly k elements of the array and paint them blue. Then, while there is at least one red element, you have to select any red element with a blue neighbor and make it blue. The cost of painting the array is defined as the sum of the first k chosen elements and the last painted element. Your task is to calculate the maximum possible cost of painting for the given array. Input The first line contains a single integer t (1≤t≤103 ) — the number of test cases. The first line of each test case contains two integers n and k (2≤n≤5000 ; 1≤k<n ). The second line contains n integers a1,a2,…,an (1≤ai≤109 ). Additional constraint on the input: the sum of n over all test cases doesn't exceed 5000 . Output For each test case, print a single integer — the maximum possible cost of painting for the given array. Example InputCopy 3 3 1 1 2 3 5 2 4 2 3 1 3 4 3 2 2 2 2 OutputCopy 5 10 8 Note In the first example, you can initially color the 2 -nd element, and then color the elements in the order 1,3 . Then the cost of painting is equal to 2+3=5 . In the second example, you can initially color the elements 1 and 5 , and then color the elements in the order 2,4,3 . Then the cost of painting is equal to 4+3+3=10 . In the third example, you can initially color the elements 2,3,4 , and then color the 1 -st element. Then the cost of painting is equal to 2+2+2+2=8 . 用cpp解决
最新发布
03-19
<think>好的,我现在需要帮助用户解决如何使用C++实现数组重着色问题的最大涂色成本计算。首先,我需要理解用户的需求。用户提到了“Array Recoloring”,也就是数组重新着色,可能涉及改变数组元素的颜色以使某些条件满足,同时计算最大成本。根据用户提供的引用[1],他们可能参考了一篇关于图像重新染色的论文,但具体代码没有公开,所以用户想自己实现。 接下来,我需要确定“最大涂色成本”具体指什么。通常,这类问题可能涉及在满足特定约束下,通过改变元素颜色使得总成本最大。例如,每次改变颜色可能需要一定的成本,或者在相邻元素颜色不同的情况下获得奖励。不过,用户没有给出具体定义,可能需要假设或参考常见问题。 查看用户提供的引用[2],有一个公式:$a[i][j] = (\sum_{x=i}^n \sum_{y=j}^m d[i][j]) \bmod 2$。这可能与二维数组的处理有关,但不确定是否直接相关。引用[3]提到高斯核和距离,可能与颜色相似性有关,但暂时可能不适用。 假设问题的大致结构是:给定一个数组,每个元素有一个颜色,可以重新着色,每次改变颜色有成本,目标是在预算内最大化某种收益,或者直接最大化总收益。或者,可能是相邻元素颜色不同时获得收益,需要安排颜色使得总收益最大。 但用户明确提到“最大涂色成本计算”,可能是指每次重新着色需要成本,而总成本是各次改变的总和,但需要最大化这个成本?这似乎不太合理,通常成本可能需要最小化。或者可能涂色本身有收益,比如不同颜色对应不同收益,选择颜色使得总收益最大。因此,可能需要更明确的问题定义。 由于用户没有给出具体的问题描述,可能需要参考常见的数组重着色问题。例如,LeetCode上有一道题目叫做“Minimum Operations to Make Array Continuous”(但这是关于连续数组的最小操作),或者“Paint House”问题,其中涂色有成本,要求相邻颜色不同,求最小成本。但用户需要的是最大涂色成本,可能与这类问题相反。 另一种可能是,每个元素可以涂成不同的颜色,每次涂色有成本,而目标是在允许的操作次内最大化总成本。或者,当相邻元素颜色不同时,获得更高的成本。这里可能需要进一步假设。 假设问题类似如下:给定一个数组,每个元素初始颜色,可以重新着色为其他颜色,每次改变颜色有特定的成本(可能与新旧颜色有关),求在允许的操作下,如何选择颜色使得总成本最大。但通常这类问题要求最小化成本,所以可能用户的问题有特殊定义。 或者,问题可能类似于:每次改变颜色需要一定的成本,而总预算是固定的,求在预算内可以改变颜色后的数组中,使得某种美观度(例如相邻不同颜色的量)最大。这种情况下,最大涂色成本可能指在预算内能达到的最大美观度。 由于用户的信息有限,可能需要基于常见问题给出一个可能的解决方案。例如,动态规划处理相邻元素的颜色选择,以最大化某种得分。或者贪心算法。 参考用户提供的引用[2]中的公式,可能涉及二维数组的处理,使用前缀和或某种模运算。例如,计算某个区域的和,然后取模决定颜色。但不确定是否直接相关。 考虑到用户希望用C++实现,需要给出具体的代码结构。例如,可能的动态规划方法,或者遍历所有可能的涂色方式,计算成本。 假设问题类似于:给定一个数组,每个元素可以涂成k种颜色,每次涂色成本为某个值,求涂色后的数组满足相邻元素颜色不同的情况下,总涂色成本最大。或者,每个颜色有不同的收益,相邻颜色不同的情况下,总收益最大。 例如,动态规划方法,其中dp[i][c]表示前i个元素,第i个元素颜色为c时的最大总成本。转移方程可能为dp[i][c] = max(dp[i-1][d] + cost(c)),其中d != c。这类似于“Paint House”问题,但求最大值。 假设问题为此,接下来需要编写C++代码。例如,给定颜色种类k,每个元素涂成颜色c的成本为cost[i][c],求最大总成本使得相邻颜色不同。 代码的大致步骤: 1. 读取输入,包括数组长度n,颜色种类k,每个元素各颜色的涂色成本。 2. 初始化动态规划数组,dp[i][c]表示第i个元素涂颜色c时的最大总成本。 3. 对于每个元素i,遍历所有可能的颜色c,找到前一个元素颜色d不等于c时的最大dp[i-1][d],加上当前cost[i][c]。 4. 最终结果就是最后一个元素所有颜色中的最大值。 例如,代码可能如下: ```cpp #include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { int n, k; cin >> n >> k; vector<vector<int>> cost(n, vector<int>(k)); for (int i = 0; i < n; ++i) { for (int j = 0; j < k; ++j) { cin >> cost[i][j]; } } vector<vector<int>> dp(n, vector<int>(k, 0)); // 初始化第一个元素 for (int c = 0; c < k; ++c) { dp[0][c] = cost[0][c]; } for (int i = 1; i < n; ++i) { for (int c = 0; c < k; ++c) { int max_prev = 0; for (int d = 0; d < k; ++d) { if (d != c) { max_prev = max(max_prev, dp[i-1][d]); } } dp[i][c] = max_prev + cost[i][c]; } } int result = 0; for (int c = 0; c < k; ++c) { result = max(result, dp[n-1][c]); } cout << result << endl; return 0; } ``` 这段代码处理每个元素选择不同颜色,且相邻颜色不同的情况下,求最大总成本。假设每个颜色的成本是给定的,比如cost[i][c]表示将第i个元素涂成颜色c的成本。这可能符合用户的问题描述。 不过,用户的问题是否如此还需要确认。例如,如果问题中的成本是改变颜色所需的代价,而初始颜色已存在,那么可能需要计算是否需要改变颜色,以及改变后的成本。例如,初始颜色数组为colors,可以改变某些元素的颜色到其他颜色,每次改变需要一定的成本,总预算是B,求在预算内改变颜色后的数组中,相邻不同颜色的对最多。此时问题转化为在预算限制下的优化问题,可能更复杂,需要使用动态规划或其他方法。 但根据用户提供的引用[2]中的公式,可能涉及二维数组和模运算,可能与位操作相关,但不确定。可能需要更详细的问题描述。不过由于用户没有提供具体的问题定义,只能根据常见情况假设。 综上,可能需要基于动态规划的方法,处理相邻颜色不同的约束,并计算最大总成本。代码结构如上,可能满足用户的需求。</think>要解决数组重着色问题中的最大涂色成本计算,可以采用动态规划方法。假设每个元素可涂$k$种颜色,相邻元素颜色不同时获得对应成本,目标是找到涂色方案使得总成本最大。 ### 实现步骤 1. **输入处理**:读取数组长度$n$和颜色种类$k$,以及每个位置各颜色的涂色成本。 2. **动态规划定义**:设$dp[i][c]$表示第$i$个元素涂颜色$c$时的最大累计成本。 3. **状态转移**:对每个位置$i$,遍历所有可能的颜色$c$,从前一位置的非$c$颜色中选择最大值进行累加。 4. **结果提取**:最终结果为最后一个元素所有颜色状态的最大值。 ### C++代码实现 ```cpp #include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { int n, k; cin >> n >> k; vector<vector<int>> cost(n, vector<int>(k)); for (int i = 0; i < n; ++i) for (int j = 0; j < k; ++j) cin >> cost[i][j]; vector<vector<int>> dp(n, vector<int>(k, 0)); // 初始化第一个元素的成本 for (int c = 0; c < k; ++c) dp[0][c] = cost[0][c]; for (int i = 1; i < n; ++i) for (int c = 0; c < k; ++c) { int max_prev = 0; for (int d = 0; d < k; ++d) if (d != c) max_prev = max(max_prev, dp[i-1][d]); dp[i][c] = max_prev + cost[i][c]; } cout << *max_element(dp[n-1].begin(), dp[n-1].end()); return 0; } ``` ### 代码说明 - **时间复杂度**:$O(nk^2)$,适用于$k$较小的场景。 - **空间优化**:可用滚动数组将空间复杂度从$O(nk)$优化到$O(k)$[^2]。 - **关键点**:通过动态规划确保相邻颜色不同,并始终选择前一位置的最大有效成本。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值