Leetcode进阶之路——Weekly Contest 141

37 篇文章 0 订阅

1089. Duplicate Zeros

1089

给定一个整型数组,若遇到0,则将其重复一遍,剩下数字后移一位,在原数组上进行操作
直接新开一个数组,遍历一遍,同时判断是否为0,最后替换原数组即可

class Solution {
public:
    void duplicateZeros(vector<int>& arr) {
		vector<int> res;
		int i = 0;
		while (res.size() < arr.size())
		{
			res.emplace_back(arr[i]);
			if (arr[i] == 0) res.emplace_back(0);
			i++;
		}
		while (res.size() > arr.size())
			res.pop_back();
		arr = res;
	}
};

1090. Largest Values From Labels
1090
给定两个数组和两个数字,数组分别为values和labels,每个value都与其下标相同的label相对应,wanted表示需要多少value,limit表示每个label最多可以被使用多少次,返回所能得到最大的value和
自定义了一个结构,保存value与label(也可以单用一个pair来保存)
然后按照value值从大到小排序,遍历一遍,判断是否达到label的上限(用map保存每个label 的使用次数),以及是否达到所需的value数目

struct valLab
{
	int value;
	int label;
};

class Solution {
public:
    int largestValsFromLabels(vector<int>& values, vector<int>& labels, int num_wanted, int use_limit) {
		valLab vl;
		vector<valLab> v;
		for (int i = 0; i < values.size(); ++i)
		{
			vl.value = values[i], vl.label = labels[i];
			v.emplace_back(vl);
		}
        
		sort(v.begin(), v.end(),
			[&](const valLab& a, const valLab& b)
		{
			return a.value > b.value;
		});
        
		unordered_map<int, int> m;
		int cnt = 0, res = 0;
		for (valLab vl : v)
		{
			if (cnt >= num_wanted) break;
			if (m[vl.label] == use_limit) continue;
			res += vl.value;
			m[vl.label] ++;
			cnt++;
		}
		return res;
	}
};

1091. Shortest Path in Binary Matrix
1091
给定一个只含有0和1的grid,判断从左上角到右下角的最短路径(可走8个方向),若不存在路径,则返回-1
这道题感觉没说清楚,也可能是我阅读理解问题?看第一个案例以为初始值为0,对角线的路径要+2,结果总是报错,后来试了下8个方向都是+1,初始值为1,才通过
很典型的bfs题了,每次保存该点是否被访问过以及是否为终点,一层层往外遍历即可
要注意当初始点或终点是1,即无法到达,直接返回-1

class Solution {
public:
    int shortestPathBinaryMatrix(vector<vector<int>>& grid) {
		int dx[8] = { 0, 0, 1, 1, 1, -1,-1, -1 };
		int dy[8] = { 1, -1,0, 1, -1, 0, 1, -1 };
		queue<pair<int, int>> q;
		int r = grid.size(), c = grid[0].size();
        if(grid[0][0] == 1 || grid[r - 1][c - 1] == 1) return -1;
		if (r + c == 0) return 0;
		vector<vector<int>> visited(r, vector<int>(c, 0));
		visited[0][0] = 1;
		q.emplace(make_pair(0, 0));
		int cnt = 1;
		while (!q.empty())
		{
			cnt++;
			queue<pair<int, int>> tmp;
			while (!q.empty())
			{
				pair<int, int> p = q.front();
				q.pop();
				for (int i = 0; i < 8; ++i) 
				{
					int x = p.first + dx[i], y = p.second + dy[i];
					if (x >= 0 && x < r && y >= 0 && y < c && visited[x][y] == 0 && grid[x][y] == 0)
					{
						if (x == r - 1 && y == c - 1) return cnt;
						visited[x][y] = 1;
						tmp.emplace(make_pair(x, y));
					}
				}
			}
			q = tmp;
		}
		return -1;
	}
};

1092. Shortest Common Supersequence
1092
给定两个字符串,找出最短序列,使其包含两个字符串
参考1092. 根据LCS(最长公共子序列)的路径逆向构造答案的思路
根据题意,既然要所得序列最短,则须保证原字符串中相同字符合并,因此需要求出两个字符串的最长公共子序列
比如以例题为例,"abac"和"cab"构成的最长公共子序列(LCS)数组为:
00000
00001
01111
01222
因此LCS长为2,此时再逆向推导构造,最后反转即可

class Solution {
public:
	string shortestCommonSupersequence(string str1, string str2) {
		int m = str1.length(), n = str2.length();
		// LCS
		vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));
		for (int i = 0; i < m; ++i)
		{
			for (int j = 0; j < n; ++j)
			{
				if (str1[i] == str2[j])
					dp[i + 1][j + 1] = dp[i][j] + 1;
				else
					dp[i + 1][j + 1] = max(dp[i][j + 1], dp[i + 1][j]);
			}
		}

		string res = "";
		while (m > 0 || n > 0)
		{
			if (m == 0)
			{
				res += str2[--n];
				continue;
			}
			if (n == 0)
			{
				res += str1[--m];
				continue;
			}
			if (str1[m - 1] == str2[n - 1])
			{
				res += str1[m - 1];
				m--, n--;
				continue;
			}

			if (dp[m][n] == dp[m][n - 1])
				res += str2[--n];
			else res += str1[--m];
		}
		reverse(res.begin(), res.end());
		return res;
	}

};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值