学渣带你刷Leetcode0126单词接龙 II  

题目描述

给定两个单词(beginWord 和 endWord)和一个字典 wordList,找出所有从 beginWord 到 endWord 的最短转换序列。转换需遵循如下规则:

每次转换只能改变一个字母。
转换过程中的中间单词必须是字典中的单词。
说明:

如果不存在这样的转换序列,返回一个空列表。
所有单词具有相同的长度。
所有单词只由小写字母组成。
字典中不存在重复的单词。
你可以假设 beginWord 和 endWord 是非空的,且二者不相同。
示例 1:

输入:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]

输出:
[
  ["hit","hot","dot","dog","cog"],
  ["hit","hot","lot","log","cog"]
]
示例 2:

输入:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

输出: []

解释: endWord "cog" 不在字典中,所以不存在符合要求的转换序列。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/word-ladder-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

白话题目:
 

算法:

 

详细解释关注 B站  【C语言全代码】学渣带你刷Leetcode 不走丢 https://www.bilibili.com/video/BV1C7411y7gB

C语言完全代码

char** list;
int** back;
int* backSize;

// DFS uses backtrack information to construct results
void dfs(char*** res, int* rSize, int** rCSizes, int* ans, int last, int retlevel) {
   int i = ans[last];
   if (i == 0) {
       res[*rSize] = (char**)malloc(sizeof(char*) * retlevel);
       (*rCSizes)[*rSize] = retlevel;
       for (int j = 0; j < retlevel; ++j) {
           res[*rSize][j] = list[ans[j]];
       }
       ++(*rSize);
   }
   if (last == 0) return;
   for (int j = 0; j < backSize[i]; ++j) {
       int k = back[i][j];
       ans[last - 1] = k;
       dfs(res, rSize, rCSizes, ans, last - 1, retlevel);
   }
}

char*** findLadders(char* beginWord, char* endWord, char** wordList, int wordListSize, int* returnSize, int** returnColumnSizes) {
   *returnSize = 0;
   int size = wordListSize + 1;  // new size
   int wlen = strlen(beginWord);
   list = (char**)malloc(sizeof(char*) * size);  // new wordlist
   back = (int**)malloc(sizeof(int*) * size);    // data to backtrack indexes while BFS
   backSize = (int*)malloc(sizeof(int) * size);
   int* visited = (int*)malloc(sizeof(int) * size);  // visited flag in BFS
   int** diff = (int**)malloc(sizeof(int*) * size);  // list diff[i] are indexes which can connect to word[i]
   int* diffSize = (int*)malloc(sizeof(int) * size);
   int endidx = 0;
   // Intialization 1
   for (int i = 0; i < size; ++i) {
       list[i] = i == 0 ? beginWord : wordList[i - 1];
       visited[i] = 0;
       diff[i] = (int*)malloc(sizeof(int) * size);
       diffSize[i] = 0;
       back[i] = (int*)malloc(sizeof(int) * size);
       backSize[i] = 0;
       if (strcmp(endWord, list[i]) == 0) {
           endidx = i;
       }
   }
   if (endidx == 0) return 0;  // endword is not in the list
   // collect diff data
   for (int i = 0; i < size; ++i) {
       for (int j = i; j < size; ++j) {
           int tmp = 0;  // tmp is the difference between word[i] & word[j]
           for (int k = 0; k < wlen; ++k) {
               tmp += list[i][k] != list[j][k];
               if (tmp > 1) break;
           }
           if (tmp == 1) {
               diff[i][diffSize[i]++] = j;
               diff[j][diffSize[j]++] = i;
           }
       }
   }
   // BFS
   int* curr = (int*)malloc(sizeof(int) * size);  // curr level in BFS
   int* prev = (int*)malloc(sizeof(int) * size);  // prev level in BFS
   int prevSize, currSize = 1;
   int* currvisited = (int*)malloc(sizeof(int) * size);  // to make sure curr members are unique
   int level = 1;                                        // level of ladder
   curr[0] = 0;
   visited[0] = 1;
   int retlevel = 0;  // ladder size, marks the end of BFS
   while (retlevel == 0 && currSize > 0) {
       ++level;
       // switch prev and curr
       int* tmp = prev;
       prev = curr;
       curr = tmp;
       prevSize = currSize;
       currSize = 0;
       // reset currvisited for each level curr
       for (int i = 0; i < size; ++i) {
           currvisited[i] = 0;
       }
       for (int i = 0; i < prevSize; ++i) {
           for (int j = 0; j < diffSize[prev[i]]; ++j) {
               int k = diff[prev[i]][j];  // k is the candidate of curr (next level of BFS)
               if (visited[k]) continue;
               back[k][backSize[k]++] = prev[i];   // backtrack
               if (k == endidx) retlevel = level;  // find the lowest ladder level, finish current BFS
               if (currvisited[k]) continue;       // no duplicates in curr list
               curr[currSize++] = k;
               currvisited[k] = 1;
           }
       }
       // set visited after search through one level, different from Q127
       for (int i = 0; i < currSize; ++i) {
           visited[curr[i]] = 1;
       }
   }
   if (retlevel == 0) return 0;  // no ladder found
   // DFS to construct result
   char*** res = (char***)malloc(sizeof(char**) * size);
   int* ans = (int*)malloc(sizeof(int) * retlevel);
   *returnColumnSizes = (int*)malloc(sizeof(int) * size);
   ans[retlevel - 1] = endidx;
   dfs(res, returnSize, returnColumnSizes, ans, retlevel - 1, retlevel);
   return res;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值