• 752.打开转盘锁 | 773.滑动谜题


    752.打开转盘锁

    你有一个带有四个圆形拨轮的转盘锁。每个拨轮都有10个数字: '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' 。每个拨轮可以自由旋转:例如把 '9' 变为 '0','0' 变为 '9' 。每次旋转都只能旋转一个拨轮的一位数字。

    锁的初始数字为 '0000' ,一个代表四个拨轮的数字的字符串。

    列表 deadends 包含了一组死亡数字,一旦拨轮的数字和列表里的任何一个元素相同,这个锁将会被永久锁定,无法再被旋转。

    字符串 target 代表可以解锁的数字,你需要给出解锁需要的最小旋转次数,如果无论如何不能解锁,返回 -1 。

    示例 1:

    输入:deadends = ["0201","0101","0102","1212","2002"], target = "0202"
    输出:6
    解释:
    可能的移动序列为 "0000" -> "1000" -> "1100" -> "1200" -> "1201" -> "1202" -> "0202"。
    注意 "0000" -> "0001" -> "0002" -> "0102" -> "0202" 这样的序列是不能解锁的,
    因为当拨动到 "0102" 时这个锁就会被锁定。
    示例 2:

    输入: deadends = ["8888"], target = "0009"
    输出:1
    解释:把最后一位反向旋转一次即可 "0000" -> "0009"。
    示例 3:

    输入: deadends = ["8887","8889","8878","8898","8788","8988","7888","9888"], target = "8888"
    输出:-1
    解释:无法旋转到目标数字且不被锁定。

    思路:

    BFS(在一幅「图」中找到从起点 start 到终点 target 的最近距离

    1. class Solution {
    2. public:
    3. int openLock(vector& deadends, string target) {
    4. int step=0;
    5. unordered_set deadSet;// 记录需要跳过的死亡数字
    6. unordered_set visited;//记录已经穷举过的密码,防止走回头路
    7. for(string s:deadends)
    8. {
    9. deadSet.insert(s);
    10. }
    11. queue q;
    12. q.push("0000");
    13. visited.insert("0000");
    14. while(!q.empty())
    15. {
    16. int size=q.size();
    17. /* 将当前队列中的所有节点向周围扩散 */
    18. for(int i=0;i
    19. {
    20. string cur=q.front();
    21. q.pop();
    22. //如果是死亡数字,就跳过这种情况
    23. if(deadSet.count(cur))
    24. {
    25. continue;
    26. }
    27. //如果等于target,就返回操作步数
    28. if(!cur.compare(target))
    29. {
    30. return step;
    31. }
    32. /* 将一个节点cur的未遍历相邻节点加入队列 */
    33. /*相邻结点有八个,四个位置,每个位置有拨上拨下两种选择*/
    34. for(int j=0;j<4;j++)
    35. {
    36. //朝上拨
    37. string s1=cur;
    38. if(s1[j]=='9')
    39. s1[j]='0';
    40. else
    41. s1[j]+=1;
    42. if(!visited.count(s1))//未遍历过,就加入队列
    43. {
    44. q.push(s1);
    45. visited.insert(s1);
    46. }
    47. //朝下拨
    48. string s2=cur;
    49. if(s2[j]=='0')
    50. s2[j]='9';
    51. else
    52. s2[j]-=1;
    53. if(!visited.count(s2))//未遍历过,就加入队列
    54. {
    55. q.push(s2);
    56. visited.insert(s2);
    57. }
    58. }
    59. }
    60. /* 在这里增加步数 */
    61. step++;
    62. }
    63. //如果穷举完都没找到目标密码,那就是找不到了
    64. return -1;
    65. }
    66. };

    773.滑动谜题

    在一个 2 x 3 的板上(board)有 5 块砖瓦,用数字 1~5 来表示, 以及一块空缺用 0 来表示。一次 移动 定义为选择 0 与一个相邻的数字(上下左右)进行交换.

    最终当板 board 的结果是 [[1,2,3],[4,5,0]] 谜板被解开。

    给出一个谜板的初始状态 board ,返回最少可以通过多少次移动解开谜板,如果不能解开谜板,则返回 -1 。

    示例 1:

    输入:board = [[1,2,3],[4,0,5]]
    输出:1
    解释:交换 0 和 5 ,1 步完成

    思路:BFS

    如何用 BFS 算法秒杀各种智力题 :: labuladong的算法小抄 (gitee.io)

    用字符串来描述board当前的状态,要把board从start状态以最小的步数转换成target=“123450”状态。 从状态cur向外扩散,即是‘ 0 ’与它周围的板块进行交换,我们通过neighbors数组来描述相邻关系。

    vectorint>> neighbors={{1,3},{0,2,4},{1,5},{0,4},{1,3,5},{2,4}};

    1. class Solution {
    2. public:
    3. void swap(string& s,int i,int j)
    4. {
    5. char temp;
    6. temp=s[i];
    7. s[i]=s[j];
    8. s[j]=temp;
    9. }
    10. int slidingPuzzle(vectorint>>& board) {
    11. string start;
    12. start.resize(6);
    13. for(int i=0;i<2;i++)//构建初始状态start
    14. {
    15. for(int j=0;j<3;j++)
    16. {
    17. start[i*3+j]=board[i][j]+'0';//注意类型转换,start中存的是字符,board中存的是数字
    18. }
    19. }
    20. //用来描述相邻关系的neighbors数组
    21. vectorint>> neighbors={{1,3},{0,2,4},{1,5},{0,4},{1,3,5},{2,4}};
    22. int step=0;
    23. string target="123450";//目标状态
    24. queue q;
    25. unordered_set visited;//防止走回头路,陷入死循环
    26. q.push(start);
    27. visited.insert(start);
    28. while(!q.empty())
    29. {
    30. int size=q.size();
    31. for(int i=0;i
    32. {
    33. string cur=q.front();
    34. if(!cur.compare(target))
    35. {
    36. return step;
    37. }
    38. int index=cur.find('0');//找到cur中'0'对应的下标
    39. q.pop();
    40. //从和'0'相邻的字符开始扩展(和'0'进行交换)
    41. for(int neighbor:neighbors[index])
    42. {
    43. string tmp=cur;
    44. swap(tmp,neighbor,index);
    45. //防止走回头路
    46. if(!visited.count(tmp))
    47. {
    48. q.push(tmp);
    49. visited.insert(tmp);
    50. }
    51. }
    52. }
    53. step++;
    54. }
    55. return -1;
    56. }
    57. };

    854. 相似度为 K 的字符串

    对于某些非负整数 k ,如果交换 s1 中两个字母的位置恰好 k 次,能够使结果字符串等于 s2 ,则认为字符串 s1 和 s2 的 相似度为 k 

    给你两个字母异位词 s1 和 s2 ,返回 s1 和 s2 的相似度 k 的最小值。

    示例 1:

    输入:s1 = "ab", s2 = "ba"
    输出:1
    

    示例 2:

    输入:s1 = "abc", s2 = "bca"
    输出:2

     思路:BFS,求最小步数

    从当前位置往后面找该位置正确的字母,交换,直至完全等于s2。

    这里要注意剪枝逻辑:

    一、如果交换完后的情况在之前出现过,再次出现的话就不用继续跑了(因为1、如果都是本层的情况,那么跑一种就够了   2、如果是上层的情况,那么现在这种肯定比上次那种步数多,也不用再跑了)。( unordered_set < string >  visited )

    二、判断要交换的那个字母,现在所在位置是否已经是正确的,如果本来就是正确的就不用换过来了。(s [ j ] ! = s2 [ j ] ) 

    1. //求最小值,所以使用BFS算法
    2. class Solution {
    3. public:
    4. int kSimilarity(string s1, string s2) {
    5. queueint>> q;
    6. unordered_set visited;//防止重复搜索字符串
    7. q.emplace(s1,0);
    8. int step=0;
    9. while(!q.empty())
    10. {
    11. int size=q.size();
    12. for(int i=0;i
    13. {
    14. pairint> cur=q.front();
    15. int index=cur.second;
    16. string s=cur.first;
    17. if(s==s2)
    18. return step;
    19. q.pop();
    20. while(indexsize()&&s[index]==s2[index])
    21. {
    22. index++;
    23. }
    24. //选择列表————s[index..]中的任意一个字符
    25. for(int j=index;jsize();j++)
    26. {
    27. //剪枝,选择s[j]!=s2[j]的字符
    28. if(s[j]==s2[index]&&s[j]!=s2[j])
    29. {
    30. swap(s[j],s[index]);
    31. if(!visited.count(s))//如果交换后的结果之前没有出现过
    32. {
    33. visited.insert(s);//记录到备忘录里
    34. q.emplace(s,index+1);//加入队列
    35. }
    36. //再交换回来,保持for循环中s不变,因为for循环中的选项都是由s引出的
    37. swap(s[j],s[index]);
    38. }
    39. }
    40. }
    41. //操作步数加一
    42. step++;
    43. }
    44. return 0;
    45. }
    46. };
  • 相关阅读:
    什么是大数据测试?有哪些类型?应该怎么测?
    图解AVLTree
    AQS(AbstractQueuedSynchronizer)框架之ReentrantLock
    【同花顺】同花顺解题
    Jtti:Ubuntu下如何创建XFS文件系统的LVM
    HarmonyOS ArkTSTabs组件的使用(六)
    嵌入式面试3(C++相关)
    排序算法之---归并排序
    使用Specification与Example方式实现动态条件查询案例
    测试覆盖率设计与实践
  • 原文地址:https://blog.csdn.net/weixin_50437588/article/details/126714086