126. Word Ladder II \ 507. Perfect Number

本文解析了 Word Ladder II 和 Perfect Number 两道算法题的解题思路与代码实现。Word Ladder II 需要找出从开始单词到目标单词的所有最短转换路径;而 Perfect Number 则需要判断一个数是否为完美数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

26. Word Ladder II

题目描述

Given two words (beginWord and endWord), and a dictionary’s word list, find all shortest transformation sequence(s) from beginWord to endWord, such that:

  • Only one letter can be changed at a time
  • Each transformed word must exist in the word list. Note that beginWord is not a transformed word.

For example,

Given:

beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log","cog"]
Return
  [
    ["hit","hot","dot","dog","cog"],
    ["hit","hot","lot","log","cog"]
  ]

Note:

  1. Return an empty list if there is no such transformation sequence.
  2. All words have the same length.
  3. All words contain only lowercase alphabetic characters.
  4. You may assume no duplicates in the word list.
  5. You may assume beginWord and endWord are non-empty and are not the same.

这道题目可以使用回溯、DFS或者BFS来计算。

代码实现

法一:回溯

这个版本的回溯是会超时的,做过一些改进依然在某些case超时。

class Solution {
public:
    int cur_shotest_len = INT_MAX;

    __inline int isClose(const string a, const string b, int len) {
        int cnt = 0;
        while(len--) 
            if(a[len] != b[len]) cnt++;
        return cnt;
    }

    void backTracking(vector<vector<string>>& res, vector<string>& cur, string beginWord, string endWord, vector<string> wordList, int size, int len, vector<int>& rec, int stt) {
        if(isClose(beginWord, endWord, len) == 0) {
            if(cur_shotest_len > cur.size()) 
                while(!res.empty()) res.pop_back();
            if(cur_shotest_len < cur.size()) return;
            cur_shotest_len = cur.size();
            res.push_back(cur);
            return;
        }

        for(int i = 0; i < size; i++) {
            if(rec[i] == 0 && cur.size() + 1 <= cur_shotest_len && isClose(beginWord, wordList[i], len) == 1) {
                rec[i] = 1;
                cur.push_back(wordList[i]);
                backTracking(res, cur, wordList[i], endWord, wordList, size, len, rec, i+1);
                cur.pop_back();
                rec[i] = 0;
            }
        }
    }

    vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {
        int size = wordList.size();
        vector<vector<string>> res;
        if(!size) return res;

        vector<string> cur;
        vector<int> rec(size, 0);
        int word_len = beginWord.size();
        cur.push_back(beginWord);
        backTracking(res, cur, beginWord, endWord, wordList, size, word_len, rec, 0);

        return res;
    }
};

对它改进的一个版本,还有一个case无法通过:

class Solution {
public:
    int cur_shotest_len = INT_MAX;
    vector<vector<string>> res;
    vector<string> cur;
    vector<vector<int>> dis;

    __inline int isClose(const string a, const string b, int len) {
        int cnt = 0;
        while(len--) 
            if(a[len] != b[len]) cnt++;
        return cnt;
    }

    void backTracking(string beginWord, string endWord, vector<string> wordList, int size, int len, int lst) {

        if(dis[lst+1][size+1] == 0) {
            if(cur_shotest_len > cur.size()) 
                while(!res.empty()) res.pop_back();
            if(cur_shotest_len < cur.size()) return;
            cur_shotest_len = cur.size();
            res.push_back(cur);
            return;
        }

        for(int i = 0; i < size; i++) {
            if(cur.size() + 1 <= cur_shotest_len) {
                if(dis[lst+1][i+1] == 1) {
                    cur.push_back(wordList[i]);
                    backTracking(wordList[i], endWord, wordList, size, len, i);
                    cur.pop_back();
                }
            }
        }
    }

    void countDis(int size, int len, string beginWord, string endWord, vector<string> wordList) {
        dis[0][size+1] = isClose( beginWord, endWord, len);
        dis[size+1][0] = dis[0][size+1];

        for(int col = 0; col < size; col++) { 
            dis[0][col+1] = isClose( beginWord, wordList[col], len);
            dis[col+1][0] = dis[0][col+1];
        }    
        for(int row = 0; row < size; row++) {
            dis[row+1][size+1] = isClose( endWord, wordList[row], len);
            dis[size+1][row+1] = dis[row+1][size+1];
        }
        for(int row = 0; row < size; row++) 
            for(int col = row+1; col < size; col++) {
                dis[row+1][col+1] = isClose( wordList[col], wordList[row], len);
                dis[col+1][row+1] = dis[row+1][col+1];
            }    
    }

    vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {
        int size = wordList.size();

        if(!size) return res;

        int word_len = beginWord.size();

        dis.resize(size+2);
        for(int i = 0; i < size+2; i++) dis[i].resize(size+2, 0);

        cur.push_back(beginWord);
        cur_shotest_len = size + 2;

        countDis(size, word_len, beginWord, endWord, wordList);

        backTracking(beginWord, endWord, wordList, size, word_len, -1);

        return res;
    }
};

上面的优化只是把距离提前计算好,然后调用。但是这个算法的瓶颈在于查找距离为一的过程。

所以需要在这个部分进行优化。

class Solution {
public:
    int cur_shotest_len = INT_MAX;
    vector<vector<string>> res;
    vector<string> cur;
    vector<vector<int>> dis;
    vector<bool> rec; // with zero

    __inline int isClose(const string a, const string b, int len) {
        int cnt = 0;
        while(len--)  if(a[len] != b[len]) cnt++;
        return cnt;
    }

    void backTracking(string beginWord, string endWord, vector<string>& wordList, int size, int len, int lst) {
        int range = dis[lst+1].size();
        for(int i = 0; i < range; i++) {
            if(cur.size() + 1 <= cur_shotest_len) {
                cur.push_back(wordList[dis[lst+1][i]-1]);
                if(rec[dis[lst+1][i]]) {
                    if(cur_shotest_len > cur.size()) 
                        while(!res.empty()) res.pop_back();
                    if(cur_shotest_len < cur.size()) { cur.pop_back(); return;}
                    cur_shotest_len = cur.size();
                    res.push_back(cur);
                    cur.pop_back();
                    return;
                }                    
                else 
                    backTracking(wordList[dis[lst+1][i] - 1], endWord, wordList, size, len, dis[lst+1][i]-1);
                cur.pop_back();
            }
        }
    }

    void countDis(int size, int len, string beginWord, string endWord, vector<string> wordList) {
        int tmp = isClose( beginWord, endWord, len);
        if(!tmp) rec[0] = true;

        for(int col = 0; col < size; col++) { 
            tmp = isClose( beginWord, wordList[col], len);
            if(tmp == 1) 
                dis[0].push_back(col+1);
        }    
        for(int row = 0; row < size; row++) {
            tmp = isClose( endWord, wordList[row], len);
            if(!tmp)  rec[row+1] = true;
        }
        for(int row = 0; row < size; row++) 
            for(int col = row+1; col < size; col++) {
                tmp = isClose( wordList[col], wordList[row], len);
                if(tmp == 1) {
                    dis[col+1].push_back(row+1);
                    dis[row+1].push_back(col+1);
                }    
            }    
    }

    vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {
        int size = wordList.size();

        if(!size) return res;

        int word_len = beginWord.size();

        dis.resize(size + 1);

        rec.resize(size + 1, false);

        cur.push_back(beginWord);
        cur_shotest_len = size + 2;

        countDis(size, word_len, beginWord, endWord, wordList);

        backTracking(beginWord, endWord, wordList, size, word_len, -1);

        return res;
    }
};

AC的代码参考了:https://discuss.leetcode.com/topic/40902/clean-but-the-best-submission-68ms-in-c-well-commented/2

现在还在优化中。。。

507. Perfect Number

题目描述

We define the Perfect Number is a positive integer that is equal to the sum of all its positive divisors except itself.

Now, given an integer n, write a function that returns true when it is a perfect number and false when it is not.

Example:

Input: 28
Output: True
Explanation: 28 = 1 + 2 + 4 + 7 + 14

Note: The input number n will not exceed 100,000,000. (1e8)

代码实现

class Solution {
public:
    bool checkPerfectNumber(int num) {
        int half = ceil(sqrt(num)), res = 1;
        for(int i = 2; i < half; i++) if(num%i == 0) {
            res += i + (num/i);
        }
        res += ceil(sqrt(num)) == floor(sqrt(num))? half:0;
        return res == num;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值