1.給定兩個單詞(beginWord 和 endWord)和一個字典,找到從 beginWord 到 endWord 的最短轉換序列的長度。轉換需遵循如下規則:
- 每次轉換隻能改變一個字母。
- 轉換過程中的中間單詞必須是字典中的單詞。
說明:
- 如果不存在這樣的轉換序列,返回 0。
- 所有單詞具有相同的長度。
- 所有單詞只由小寫字母組成。
- 字典中不存在重複的單詞。
- 你可以假設 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<string>& wordList) {
unordered_set<string> 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<string> 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<string> 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<vector<char>>& 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<vector<char>>& 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<char>> 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<vector<int>>& prerequisites) {
const int N = INT8_MAX;
vector<int> 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<int> 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<int>> 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<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
vector<int> heads(numCourses, -1), degree(numCourses, 0), points, args;
pair<int, int> p;
vector<int> 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<int> 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<int>();
return ans;
}
};
int main()
{
Solution s1;
vector < vector<int>> ss = { {1,0} };
vector<int> s;
s = s1.findOrder(2,ss);
return 0;
}