1.给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度。转换需遵循如下规则:
说明:
示例 1:
输入: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
输出: 5
解释: 一个最短转换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog", 返回它的长度 5。
using namespace std;
class Solution {
public:
int ladderLength(string beginWord, string endWord, vector& wordList) {
unordered_set dict(wordList.begin(), wordList.end()), head, tail, *phead, *ptail;
if (dict.find(endWord) == dict.end()) {
return 0; //结束字符不在字典中则直接返回0
}
head.insert(beginWord);
tail.insert(endWord);
int ladder = 2;
while (!head.empty() && !tail.empty()) {
if (head.size() < tail.size()) {
phead = &head;
ptail = &tail;
}
else {
phead = &tail;
ptail = &head;
}
unordered_set temp;
for (auto it = phead->begin(); it != phead->end(); it++) {
string word = *it;
for (int i = 0; i < word.size(); i++) {
char t = word[i];
for (int j = 0; j < 26; j++) {
word[i] = 'a' + j;
if (ptail->find(word) != ptail->end()) {
return ladder;
}
if (dict.find(word) != dict.end()) {
temp.insert(word);
dict.erase(word);
}
}
word[i] = t;
}
}
ladder++;
phead->swap(temp);
}
return 0;
}
};
int main()
{
Solution s1;
vector ss = { "hot","dot","dog","lot","log","cog" };
cout << s1.ladderLength("hit","cog",ss);
return 0;
}
2.给定一个由 '1'
(陆地)和 '0'
(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。
输入: 11110 11010 11000 00000
输出: 1
解:递归调用infect函数,利用深度搜索,遇到1时,它的上下左右都被改为2
代码:
using namespace std;
class Solution {
public:
int numIslands(vector>& grid) {
if (grid.empty() || grid[0].empty()) {
return 0; //行空 或 列空
}
int N = grid.size();//grid网格的列长
int M = grid[0].size();//grid网格的行长
int res = 0;
//深度优先搜索
for (int i = 0; i < N; ++i) {
for (int j = 0; j < M; ++j) {
if (grid[i][j] == '1') {
++res;//只计数作为起始感染点的1的个数,即为岛屿个数
infect(grid, i, j, N, M);
}
}
}
return res;
}
void infect(vector>& grid, int i, int j, int N, int M) {
if (i < 0 || i >= N || j < 0 || j >= M || grid[i][j] != '1') {
return;
}
grid[i][j] = '2';
infect(grid, i + 1, j, N, M);
infect(grid, i - 1, j, N, M);
infect(grid, i, j - 1, N, M);
infect(grid, i, j + 1, N, M);
}
};
int main()
{
Solution s1;
vector < vector> ss = { {'1','1','0','0','0'} ,{'1','1','0','0','0'},{'0','0','1','0','0'},{'0','0','0','1','1'} };
cout << s1.numIslands(ss);
return 0;
}
3.现在你总共有 n 门课需要选,记为 0
到 n-1
。
在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1]
给定课程总量以及它们的先决条件,判断是否可能完成所有课程的学习?
示例 1:
输入: 2, [[1,0]]
输出: true
解释: 总共有 2 门课程。学习课程 1 之前,你需要完成课程 0。所以这是可能的。
代码:
using namespace std;
class Solution {
public:
bool canFinish(int numCourses, vector>& prerequisites) {
const int N = INT8_MAX;
vector head[N], res;
int du[N] = { 0 }, n = numCourses;
int len = prerequisites.size();
//根据课程表,构建有向图
for (int i = 0; i < len; i++) {
int aft = prerequisites[i][0];
int pre = prerequisites[i][1];
du[aft]++;
head[pre].push_back(aft);
}
//将第一个要修的课程,即du为0的课程压入队列中
queue q;
for (int i = 0; i < n; i++) {
if (!du[i]) q.push(i);
}
//依次按照有向图的方向,将所有课程按顺序放入数组中
while (!q.empty()) {
int top = q.front();
q.pop();
res.push_back(top);
du[top] = -1;
for (auto x : head[top]) {
du[x]--;
if (!du[x]) q.push(x);
}
}
return n == res.size();
}
};
int main()
{
Solution s1;
vector < vector> ss = { {1,0} };
cout << s1.canFinish(2,ss);
return 0;
}
4.现在你总共有 n 门课需要选,记为 0
到 n-1
。
在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1]
给定课程总量以及它们的先决条件,返回你为了学完所有课程所安排的学习顺序。
可能会有多个正确的顺序,你只要返回一种就可以了。如果不可能完成所有课程,返回一个空数组。
示例 1:
输入: 2, [[1,0]]
输出: [0,1]
解释: 总共有 2 门课程。要学习课程 1,你需要先完成课程 0。因此,正确的课程顺序为 [0,1] 。
代码:
class Solution {
public:
vector findOrder(int numCourses, vector>& prerequisites) {
vector heads(numCourses, -1), degree(numCourses, 0), points, args;
pair p;
vector ans;
int from, to, count = 0, len = prerequisites.size();
/* 构造有向图,邻接表 */
for (int i = 0; i < len; ++i) {
from = prerequisites[i][1];
to = prerequisites[i][0];
++degree[to];
args.push_back(heads[from]);
points.push_back(to);
heads[from] = count++;
}
/* bfs拓扑排序,依次移除入度为0的点 */
queue q;
for (int i = 0; i < numCourses; ++i)
if (degree[i] == 0) {
q.push(i);
ans.push_back(i);
}
while (!q.empty()) {
from = q.front();
q.pop();
to = heads[from];
while (to != -1) {
if (--degree[points[to]] == 0) {
q.push(points[to]);
ans.push_back(points[to]);
}
to = args[to];
}
}
/* 判定是否所有的点入度都为0,若是则不存在环,否则存在环 */
for (int i = 0; i < numCourses; ++i)
if (degree[i] > 0)
return vector();
return ans;
}
};
int main()
{
Solution s1;
vector < vector> ss = { {1,0} };
vector s;
s = s1.findOrder(2,ss);
return 0;
}