2215. 找出两数组的不同
-
题目大意
给定两个列表nums1和nums2,输出num1不存在nums2中的数字,和nums2不存在nums1中的数字。 -
思路
开数组map一下,不要直接用map,比较麻烦,容易出各种编译错误!、记得去重。 -
code
class Solution {
public:
vector<vector<int>> findDifference(vector<int>& nums1, vector<int>& nums2) {
int n1=nums1.size(),n2=nums2.size();
int p1[2010]={0},p2[2010]={0};
int f1[2010]={0},f2[2010]={0};
map<int,int> mp1,mp2;
vector<vector<int>> ans(2,vector<int>());
for(int i=0;i<n1;i++) p1[nums1[i]+1000]++;
for(int i=0;i<n2;i++) p2[nums2[i]+1000]++;
for(int i=0;i<n1;i++){
if(p2[nums1[i]+1000]==0 && f1[nums1[i]+1000]==0){
ans[0].push_back(nums1[i]);
f1[nums1[i]+1000]=1;
}
}
for(int i=0;i<n2;i++){
if(p1[nums2[i]+1000]==0 && f2[nums2[i]+1000]==0){
ans[1].push_back(nums2[i]);
f2[nums2[i]+1000]=1;
}
}
return ans;
}
};
2216. 美化数组的最少删除数
- 题目大意
当偶数下标的数字和他后一个技术下标的数字不同时,则认为一个序列是“美丽数组”。你可以每次操作可以删除任意位置的数字,问最少删除多少个数使得现有数组变成美丽数组。 - 思路
贪心。
要注意,删除一个数字后,后面的数字的下标奇偶性都会发生改变。 - code
class Solution {
public:
int minDeletion(vector<int>& nums) {
int n = nums.size();
int ans = 0;
for (int i = 0; i + 1 < n; i++) {
if (nums[i] == nums[i + 1]) ans++;
else i++;
}
if ((n - ans) % 2) ans++;
return ans;
}
};
2217. 找到指定长度的回文数
-
题目大意
返回给定长度为intLength的第queries[i]个回文数。(其中回文数是由0-9数字组成的)。 -
思路
可以发现,回文数的数量和回文数的形态是有规律的:
第i个回文数就是这个回文数前一半的数字是长度为intLength的自然数后的第几个(一个回文数是由他的前一半完全决定的):前一半 = left + queries[i] - 1。
然后根据长度的奇偶,在反着把剩下一半找到即可。 -
code
class Solution {
public:
vector<long long> kthPalindrome(vector<int>& queries, int intLength) {
int n = queries.size();
vector<long long> ans(n, -1);
/* 求出[l,r]的构造区间 */
int left = pow(10, (intLength + 1) / 2 - 1);
int right = left * 10;
for (int i = 0; i < n; i++) {
if (queries[i] > right - left) {
continue;
}
/* 根据该回文数的一半, 求出该回文数 */
int cur = left + queries[i] - 1;
long long sum = cur;
int x = (intLength % 2 == 1) ? cur / 10 : cur;
while (x > 0) {
sum = sum * 10 + x % 10;
x /= 10;
}
ans[i] = sum;
}
return ans;
}
};
2218. 从栈中取出 K 个硬币的最大面值和
-
题目大意
有 n n n个栈,每个栈里有 p l i e s [ i ] plies[i] plies[i]个硬币,每个硬币的面值为 p i l e s [ i ] [ j ] piles[i][j] piles[i][j],你可以取 k k k次,问最终手里最多有价值多少的硬币。 -
思路
经典背包 dp,算是简单dp题了。
记 f i , j f_{i, j} fi,j表示考虑到第 i i i个栈,一共已经取出了 j j j 个硬币的最大面值和。有转移方程: f i , j = max ( f i − 1 , j − t + s i , t ) f_{i, j} = \max (f_{i - 1, j - t} + s_{i, t}) fi,j=max(fi−1,j−t+si,t),表示从第 i i i个栈中取出 t t t个硬币( t t t为非负整数,不能超过第 t t t个栈的大小 p i p_i pi ), s i , t s_{i, t} si,t 表示第 i i i个栈中前 t t t个硬币的面值和。答案就是 f n , k f_{n, k} fn,k。复杂度 O ( k ∑ i = 1 n p i ) \mathcal{O}(k\sum\limits_{i=1}^n p_i) O(ki=1∑npi)。 -
code
class Solution {
public:
int maxValueOfCoins(vector<vector<int>>& piles, int k) {
int n = piles.size();
int s[1010][2010];
vector<vector<int>> f(n+1, vector<int>(k+1));
for(int i=0;i<n;i++)
{
s[i][0]=piles[i][0];
for(int j=1;j<piles[i].size();j++)
s[i][j]=s[i][j-1]+piles[i][j];
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=k;j++)
{
f[i][j]=f[i-1][j];
int x = piles[i-1].size();
for(int t=1;t<=min(j,x);t++)
{
f[i][j]=max(f[i-1][j-t]+s[i-1][t-1],f[i][j]);
}
}
}
return f[n][k];
}
};