当前位置:网站首页>leetcode——启发式搜索
leetcode——启发式搜索
2022-04-23 04:49:00 【csdn_ggboy】
847. 访问所有节点的最短路径 - 力扣(LeetCode)
一个很重要的优化,起点一定是连接节点个数最少的,这样保证了路径最短
class Solution
{
public:
struct state
{
int now;
int loc;
int dist; //这是比较用的dist,dis + astar
//返回值是bool类型,重载运算符<, 右边参数为不能修改的引用,这个函数不会修改结构体的值
bool operator<(const state &rhs) const
{
return dist > rhs.dist;
}
};
int astar(int loc)
{
// 1的数量表示还需要去哪些点
int res = 0;
while (loc)
{
loc -= (loc & -loc);
res++;
}
return res;
}
int shortestPathLength(vector<vector<int>> &graph)
{
int n = graph.size();
int ans = 0x3f3f3f3f;
int mi = 0x3f3f3f3f;
for(auto &p: graph)
mi=min(mi, (int)p.size());
unordered_map<int, unordered_map<int, int>> dist;
priority_queue<state, vector<state>> q;
for (int i = 0; i < n; i++)
{
//起点i
if(graph[i].size() != mi) continue;
int loc = ((1 << n) - 1) ^ (1 << i);
dist[i][loc] = 0;
q.push({
i, loc, n - 1});
}
while (q.size())
{
auto t = q.top();
q.pop();
int u = t.now;
int d = astar(t.loc);
if(d > astar(t.loc) + dist[u][t.loc]) continue;
if (astar(t.loc) == 0)
{
ans = min(ans, t.dist);
break;
}
for (int j = 0; j < graph[u].size(); j++)
{
int nx = graph[u][j];
int nloc = t.loc;
if (t.loc & (1 << nx))
nloc ^= (1 << nx);
//如果nx位置没有走过,更新nloc
// if(st[nx][nloc]) continue;
if (!dist.count(nx) || !dist[nx].count(t.loc) || dist[nx][nloc] > dist[u][t.loc] + 1)
{
dist[nx][nloc] = dist[u][t.loc] + 1;
q.push({
nx, nloc, dist[nx][nloc] + astar(nloc)});
}
}
}
return ans;
}
};
127. 单词接龙 - 力扣(LeetCode)
class Solution
{
public:
typedef pair<int,int> PII;
bool edgeif(string a, string b)
{
unordered_map<char, int> mp;
if (a == b)
return true;
bool flag = false;
for (int i = 0; i < a.size(); i++)
{
if (a[i] != b[i] && !flag)
{
flag = true;
}
else if(a[i] != b[i] && flag)
return false;
}
return true;
}
int astar(int _a, int _end, vector<string> &wordList)
{
string a = wordList[_a];
string end = wordList[_end];
if (a.size() != end.size())
return 0x3f3f3f3f;
int res = 0;
for (int i = 0; i < a.size(); i++)
{
if (a[i] != end[i])
res++;
}
return res;
}
int ladderLength(string beginWord, string endWord, vector<string> &wordList)
{
wordList.push_back(beginWord);
if (find(wordList.begin(), wordList.end(), endWord) == wordList.end())
return 0;
wordList.push_back(endWord);
int n = wordList.size();
unordered_map<string, int> mp;
for(int i = 0; i < wordList.size(); i ++) mp[wordList[i]] = i;
int dist[n];
bool st[n];
memset(dist, 0x3f3f3f3f, sizeof(dist));
memset(st, 0, sizeof(st));
dist[n - 2] = 0;
st[n - 2] = true;
priority_queue<PII, vector<PII>, greater<PII>> q;
q.push({
astar(n - 2, n - 1, wordList), n - 2});
while (q.size())
{
auto t = q.top();
q.pop();
int u = t.second;
if(u == n - 1) break;
st[u] = false;
for(int i = 0; i < 26; i ++ )
for(int j = 0; j < wordList[u].size(); j ++)
{
string now = wordList[u];
if(now[j] != 'a' + i)
{
now[j] = 'a' + i;
}
if(!mp.count(now))
continue;
int to = mp[now];
if (st[to])
continue;
int d_a = astar(to, n - 1, wordList);
if (dist[to] > dist[u] + 1 )
{
dist[to] = dist[u] + 1;
st[to] = true;
q.push({
dist[to] + d_a, to});
}
}
}
if (dist[n - 1] >= 0x3f3f3f3f)
return 0;
return dist[n - 1] + 1;
}
};
752. 打开转盘锁 - 力扣(LeetCode)
class Solution
{
public:
// 0 1 2 3 4 5 6 7 8 9
typedef pair<int, string> PIS;
int astar(string a, string target)
{
int res = 0;
for (int i = 0; i < a.size(); i++)
{
res += min((a[i] - target[i] + 10) % 10, (-a[i] + target[i] + 10) % 10);
}
return res;
}
int openLock(vector<string> &deadends, string target)
{
if(target == "0000") return 0;
//每个数字可以有两个旋转方式,每次可以选择一个位置旋转,不能旋转到死亡数字
priority_queue<PIS, vector<PIS>, greater<PIS>> q;
unordered_map<string, bool> st;
unordered_map<string, int> dist;
for (auto p : deadends)
st[p] = true; //标记死亡状态
if (!st["0000"])
{
q.push({
astar("0000", target), "0000"}); //初始状态
st["0000"] = true;
}
bool flag = false;
while (!q.empty())
{
auto u = q.top();
string t = u.second;
st[t] = false;
q.pop();
if (t == target)
{
break;
}
for (int i = 0; i < 4; i++) //找一个位置
{
string ne = t;
ne[i] = (t[i] - '0' + 1) % 10 + '0';
if (!st[ne])
{
if (!dist.count(ne) || dist[ne] > dist[t] + 1)
{
dist[ne] = dist[t] + 1;
st[ne] = true;
q.push({
dist[ne] + astar(ne, target), ne});
}
}
ne[i] = (t[i] - '0' - 1 + 10) % 10 + '0';
if (!st[ne])
{
if (!dist.count(ne) || dist[ne] > dist[t] + 1)
{
dist[ne] = dist[t] + 1;
st[ne] = true;
q.push({
dist[ne] + astar(ne, target), ne});
}
}
}
}
if (dist.count(target))
return dist[target];
else
return -1;
}
};
773. 滑动谜题 - 力扣(LeetCode)
#define x first
#define y second
class Solution {
public:
string end = "123450";
int dx[4] = {
0, 0, 1, -1}, dy[4] = {
1, -1, 0, 0};
typedef pair<int, string> PIS;
int f(string s)
{
int res = 0;
for(int i = 0; i < s.size(); i ++ )
if(s[i] != '0')
{
int p = s[i] - '1';
res += abs(i / 3 - p / 3) + abs(i % 3 - p % 3);
}
return res;
}
int bfs(string state)
{
unordered_map <string, int> dist;
priority_queue <PIS, vector<PIS>, greater<PIS>> q;
unordered_map <string, bool> st;
st[state] = true;
q.push({
f(state), state});//将初始状态入栈
dist[state] = 0;
while(q.size())
{
auto t = q.top();
q.pop();
string s = t.y;
if(s == end) break;
st[s] = false;
int x, y;
for(int i = 0; i < 6; i ++ )//找到0的位置
{
if(s[i] == '0')
{
x = i / 3;
y = i % 3;
break;
}
}
for(int i = 0; i < 4; i ++ )//和上下左右交换
{
int nx = x + dx[i], ny = y + dy[i];
if(nx < 0 || ny < 0 || nx > 1 || ny > 2) continue;//两行三列
string source = s;
swap(source[x * 3 + y], source[nx * 3 + ny]);
if(st[source]) continue;
if(!dist.count(source) || dist[source] > dist[s] + 1)//dist是无穷大或者是比s + 1大
{
dist[source] = dist[s] + 1;
q.push({
f(source) + dist[source], source});
}
}
}
return dist[end];
}
int slidingPuzzle(vector<vector<int>>& board) {
//A* 多次入栈,终点出栈只能确定终点的最短路径
//判断是否有解
string start;
for(auto &t : board)
for(auto &x : t)
start += x + '0';
int cnt = 0;
for(int i = 0; i < 6; i ++ )
for(int j = i + 1; j < 6; j ++ )
{
if(start[i] != '0' && start[j] != '0' && start[j] < start[i]) cnt ++;
}
if(cnt % 2) return -1;
else return bfs(start);
}
};
版权声明
本文为[csdn_ggboy]所创,转载请带上原文链接,感谢
https://blog.csdn.net/csdn_ggboy/article/details/124291327
边栏推荐
- Perfect test of coil in wireless charging system with LCR meter
- Youqilin 22.04 lts version officially released | ukui 3.1 opens a new experience
- [paper reading] [3D object detection] voxel transformer for 3D object detection
- Improving 3D object detection with channel wise transformer
- AWS eks add cluster user or Iam role
- MySQL -- execution process and principle of a statement
- Druid -- JDBC tool class case
- What's the difference between error and exception
- Excel protects worksheets and workbooks from damage
- Graduation project
猜你喜欢
Learning Android II from scratch - activity
Excel protects worksheets and workbooks from damage
Painless upgrade of pixel series
使用model.load_state_dict()时,出现AttributeError: ‘str‘ object has no attribute ‘copy‘
Use model load_ state_ Attributeerror appears when dict(): 'STR' object has no attribute 'copy‘
Summary of MySQL de duplication methods
Record the ThreadPoolExecutor main thread waiting for sub threads
Innovation training (IX) integration
Teach you how to build the ruoyi system by Tencent cloud
Perfect test of coil in wireless charging system with LCR meter
随机推荐
Excel uses the functions of replacement, sorting and filling to comprehensively sort out financial data
leetcode003--判断一个整数是否为回文数
【数据库】表的查看、修改和删除
New terminal play method: script guidance independent of technology stack
Druid -- JDBC tool class case
Mysql50 basic exercises
Leetcode005 -- delete duplicate elements in the array in place
Innovation training (II) task division
Windows remote connection to redis
Leetcode - > 1 sum of two numbers
Sword finger offer: the path with a certain value in the binary tree (backtracking)
Create VPC in AWS console (no plate)
Improving 3D object detection with channel wise transformer
Spark optimization
Custom switch control
Spark case - wordcount
Better way to read configuration files than properties
Luogu p1858 [multi person knapsack] (knapsack seeking the top k optimal solution)
What is a data island? Why is there still a data island in 2022?
[timing] empirical evaluation of general convolution and cyclic networks for sequence modeling based on TCN