《LeetCode 顺序刷题》61 - 70

61、[中等] 旋转链表

链表

复制代码
class Solution {
public:
    ListNode* rotateRight(ListNode* head, int k) {
        if (k == 0 || head == nullptr || head->next == nullptr) {
            return head;
        }
        int n = 1;
        ListNode* iter = head;
        while (iter->next) {
            iter = iter->next;
            n++;
        }
        int add = n - k % n;
        if (add == n) {
            return head;
        }
        iter->next = head;
        while (add--) {
            iter = iter->next;
        }
        ListNode* ret = iter->next;
        iter->next = nullptr;
        return ret;
    }
};

62、[中等] 不同路径

数学 动态规划

动态规划

复制代码
class Solution {
public:
    int uniquePaths(int m, int n) {
        // 初始化 F(0, j) = F(i, 0) = 1;
        vector<vector<int>> dp(m, vector(n, 1));

        for (int i = 1; i < m; ++i) {
            for (int j = 1; j < n; ++j) {
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
            }
        }

        return dp[m - 1][n - 1];
    }
};

备忘录

复制代码
class Solution {
public:
    int uniquePaths(int m, int n) {
        vector<vector<int>> memo(m + 1, vector<int>(n + 1));
        return dfs(m, n, memo);
    }

    int dfs(int i, int j, vector<vector<int>>& memo) {
        if (memo[i][j] != 0) {
            return memo[i][j];
        }

        if (i == 0 || j == 0) {
            return 0;
        }
        if (i == 1 && j == 1) {
            memo[i][j] = 1;
            return memo[i][j];
        }

        memo[i][j] = dfs(i - 1, j, memo) + dfs(i, j - 1, memo);
        return memo[i][j];
    }
};

63、[中等] 不同路径 Ⅱ

数学 动态规划 矩阵

动态规划

复制代码
class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
        int row = obstacleGrid.size();
        int col = obstacleGrid[0].size();
        vector<vector<int>> dp(row + 1, vector(col + 1, 0));
        dp[0][1] = 1;

        for (int i = 1; i <= row; ++i) {
            for (int j = 1; j <= col; ++j) {
                if (obstacleGrid[i - 1][j - 1] != 1) {
                    dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
                } else {
                    dp[i][j] = 0;
                }
            }
        }

        return dp[row][col];
    }
};

class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
        int row = obstacleGrid.size();
        int col = obstacleGrid[0].size();
        vector<vector<int>> pathNum(row, vector(col, 1));

        for (int i = 0; i < row; ++i) {
            for (int j = 0; j < col; ++j) {
                if (obstacleGrid[i][j] == 1) {
                    pathNum[i][j] = 0;
                } else {
                    if (i == 0 && j == 0) {
                        pathNum[i][j] = 1;
                    } else if (i == 0) {
                        pathNum[i][j] = pathNum[i][j - 1];
                    } else if (j == 0) {
                        pathNum[i][j] = pathNum[i - 1][j];
                    } else {
                        pathNum[i][j] = pathNum[i - 1][j] + pathNum[i][j - 1];
                    }
                }
            }
        }

        return pathNum[row - 1][col - 1];
    }
};

class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
        int row = obstacleGrid.size();
        int col = obstacleGrid[0].size();
        vector<int> dp(col);
        dp[0] = (obstacleGrid[0][0] == 0);

        for (int i = 0; i < row; ++i) {
            for (int j = 0; j < col; ++j) {
                if (obstacleGrid[i][j] == 1) {
                    dp[j] = 0;
                    continue;
                }

                if (j - 1 >= 0 && obstacleGrid[i][j - 1] == 0) {
                    dp[j] += dp[j - 1];
                }
            }
        }

        return dp[col - 1];
    }
};

64、[中等] 最小路径和

数组 动态规划 矩阵

复制代码
class Solution {
public:
    int minPathSum(vector<vector<int>>& grid) {
        int row = grid.size();
        int col = grid[0].size();
        vector<vector<int>> dp(row, vector<int>(col));
        dp[0][0] = grid[0][0];
        for (int i = 1; i < row; ++i) {
            dp[i][0] = dp[i - 1][0] + grid[i][0];
        }
        for (int j = 1; j < col; ++j) {
            dp[0][j] = dp[0][j - 1] + grid[0][j];
        }
        for (int i = 1; i < row; ++i) {
            for (int j = 1; j < col; ++j) {
                dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
            }
        }
        return dp[row - 1][col - 1];
    }
};

65、[困难] 有效数字

字符串

确定有限状态自动机

复制代码
class Solution {
private:
    enum State {
        STATE_INITIAL,
        STATE_INT_SIGN,
        STATE_INTEGER,
        STATE_POINT,
        STATE_POINT_WITHOUT_INT,
        STATE_FRACTION,
        STATE_EXP,
        STATE_EXP_SIGN,
        STATE_EXP_NUMBER,
        STATE_END
    };

    enum CharType {
        CHAR_NUMBER,
        CHAR_EXP,
        CHAR_POINT,
        CHAR_SIGN,
        CHAR_ILLEGAL
    };

    CharType toCharType(char ch) {
        if (ch >= '0' && ch <= '9') {
            return CHAR_NUMBER;
        } else if (ch == 'e' || ch == 'E') {
            return CHAR_EXP;
        } else if (ch == '.') {
            return CHAR_POINT;
        } else if (ch == '+' || ch == '-') {
            return CHAR_SIGN;
        } else {
            return CHAR_ILLEGAL;
        }
    }

public:
    bool isNumber(string s) {
        unordered_map<State, unordered_map<CharType, State>> transfer{
            {STATE_INITIAL,
             {{CHAR_NUMBER, STATE_INTEGER},
              {CHAR_POINT, STATE_POINT_WITHOUT_INT},
              {CHAR_SIGN, STATE_INT_SIGN}}},
            {STATE_INT_SIGN,
             {{CHAR_NUMBER, STATE_INTEGER},
              {CHAR_POINT, STATE_POINT_WITHOUT_INT}}},
            {STATE_INTEGER,
             {{CHAR_NUMBER, STATE_INTEGER},
              {CHAR_EXP, STATE_EXP},
              {CHAR_POINT, STATE_POINT}}},
            {STATE_POINT,
             {{CHAR_NUMBER, STATE_FRACTION}, {CHAR_EXP, STATE_EXP}}},
            {STATE_POINT_WITHOUT_INT, {{CHAR_NUMBER, STATE_FRACTION}}},
            {STATE_FRACTION,
             {{CHAR_NUMBER, STATE_FRACTION}, {CHAR_EXP, STATE_EXP}}},
            {STATE_EXP,
             {{CHAR_NUMBER, STATE_EXP_NUMBER}, {CHAR_SIGN, STATE_EXP_SIGN}}},
            {STATE_EXP_SIGN, {{CHAR_NUMBER, STATE_EXP_NUMBER}}},
            {STATE_EXP_NUMBER, {{CHAR_NUMBER, STATE_EXP_NUMBER}}}};

        int len = s.length();
        State st = STATE_INITIAL;

        for (int i = 0; i < len; i++) {
            CharType typ = toCharType(s[i]);
            if (transfer[st].find(typ) == transfer[st].end()) {
                return false;
            } else {
                st = transfer[st][typ];
            }
        }
        return st == STATE_INTEGER || st == STATE_POINT ||
               st == STATE_FRACTION || st == STATE_EXP_NUMBER ||
               st == STATE_END;
    }
};

66、[简单] 加一

数组

复制代码
class Solution {
public:
    vector<int> plusOne(vector<int>& digits) {
        int n = digits.size();
        int add = digits[n - 1] + 1;
        vector<int> ret;
        ret.push_back(add % 10);
        add /= 10;
        for (int i = n - 2; i >= 0; i--) {
            add += digits[i];
            ret.push_back(add % 10);
            add /= 10;
        }
        if (add) {
            ret.push_back(add);
        }
        reverse(ret.begin(), ret.end());
        return ret;
    }
};

class Solution {
public:
    vector<int> plusOne(vector<int>& digits) {
        int n = digits.size();
        for (int i = n - 1; i >= 0; i--) {
            if (digits[i] != 9) {
                digits[i]++;
                for (int j = i + 1; j < n; j++) {
                    digits[j] = 0;
                }
                return digits;
            }
        }

        // digits 中所有的元素均为 9
        vector<int> ret(n + 1);
        ret[0] = 1;
        return ret;
    }
};

67、[简单] 二进制求和

位运算

复制代码
class Solution {
public:
    string addBinary(string a, string b) {
        string ret;
        int cur1 = a.size() - 1;
        int cur2 = b.size() - 1;
        int add = 0;

        while (cur1 >= 0 || cur2 >= 0 || add) {
            if (cur1 >= 0) {
                add += a[cur1--] - '0';
            }
            if (cur2 >= 0) {
                add += b[cur2--] - '0';
            }
            ret += add % 2 + '0';
            add /= 2;
        }
        reverse(ret.begin(), ret.end());

        return ret;
    }
};

68、[困难] 文本左右对齐

数组 字符串

复制代码
class Solution {
private:
    // blank 返回长度为 n 的由空格组成的字符串
    string blank(int n) { return string(n, ' '); }

    // join 返回用 sep 拼接 [left, right) 范围内的 words 组成的字符串
    string join(vector<string>& words, int left, int right, string sep) {
        string s = words[left];
        for (int i = left + 1; i < right; i++) {
            s += sep + words[i];
        }
        return s;
    }

public:
    vector<string> fullJustify(vector<string>& words, int maxWidth) {
        vector<string> ret;
        int right = 0, n = words.size();
        while (true) {
            int left = right; // 当前行的第一个单词在 words 的位置
            int sumLen = 0;
            // 循环确定当前行可以放多少单词,注意单词之间应至少有一个空格
            while (right < n && sumLen + words[right].length() + right - left <= maxWidth) {
                sumLen += words[right++].length();
            }

            // 当前行是最后一行:单词左对齐,且单词之间应只有一个空格,在行末填充剩余空格
            if (right == n) {
                string s = join(words, left, n, " ");
                ret.emplace_back(s + blank(maxWidth - s.length()));
                return ret;
            }

            int numWords = right - left;
            int numSpaces = maxWidth - sumLen;

            // 当前行只有一个单词:该单词左对齐,在行末填充剩余空格
            if (numWords == 1) {
                ret.emplace_back(words[left] + blank(numSpaces));
                continue;
            }

            // 当前行不只一个单词
            int avgSpaces = numSpaces / (numWords - 1);
            int extraSpaces = numSpaces % (numWords - 1);
            string s1 = join(words, left, left + extraSpaces + 1, blank(avgSpaces + 1)); // 拼接额外加一个空格的单词
            string s2 = join(words, left + extraSpaces + 1, right, blank(avgSpaces)); // 拼接其余单词
            ret.emplace_back(s1 + blank(avgSpaces) + s2);
        }
    }
};

69、[简单] x 的平方根

数学 二分查找

复制代码
class Solution {
public:
    int mySqrt(int x) {
        if (x < 1) {
            return 0;
        }

        int left = 1, right = x;
        while (left < right) {
            long long mid = left + (right - left + 1) / 2;
            if (mid * mid <= x) {
                left = mid;
            } else {
                right = mid - 1;
            }
        }

        return left;
    }
};

70、[简单] 爬楼梯

数学 动态规划

动态规划

复制代码
class Solution {
public:
    int climbStairs(int n) {
        int p = 0, q = 0, r = 1;
        for (int i = 1; i <= n; ++i) {
            p = q;
            q = r;
            r = p + q;
        }
        return r;
    }
};

class Solution {
public:
    int climbStairs(int n) {
        vector<int> dp(n + 1);
        dp[0] = dp[1] = 1;
        for (int i = 2; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }
};
相关推荐
岁岁的O泡奶1 小时前
NSSCTF_crypto_[LitCTF 2023]babyLCG
经验分享·python·算法·密码学·crypto·流密码
风落无尘1 小时前
我用 LangChain 写了一个带“定速巡航”的向量化工具,发布到 PyPI 了!
人工智能·python·langchain
AI技术控1 小时前
RAG 效果差不是模型问题:10 个检索增强失败原因总结
人工智能·python·自然语言处理
想唱rap2 小时前
应用层HTTPS协议
服务器·网络·c++·网络协议·http·https
敲代码的瓦龙2 小时前
Android?基础UI控件!!!
java·开发语言
Hesionberger2 小时前
LeetCode 78:子集生成全攻略
java·开发语言·数据结构·python·算法·leetcode·职场和发展
bzmK1DTbd2 小时前
Swagger API文档:Java RESTful服务的自动生成
java·开发语言·restful
前端之虎陈随易2 小时前
为什么今天还会有新语言?MoonBit 想解决什么问题?
大数据·linux·javascript·人工智能·算法·microsoft·typescript
G.晴天2 小时前
Linux常用命令练习流程
java·linux·运维·服务器·tomcat