79. Word Search\513. Find Bottom Left Tree Value\110. Balanced Binary Tree

本文提供了LeetCode上的三道经典题目解答:WordSearch题通过深度优先搜索寻找矩阵中的目标字符串;FindBottomLeftTreeValue题求解二叉树最底层最左边的节点值;BalancedBinaryTree题判断二叉树是否高度平衡。

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

题目描述

Given a 2D board and a word, find if the word exists in the grid.

The word can be constructed from letters of sequentially adjacent cell, where “adjacent” cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.

For example,
Given board =

[
  ['A','B','C','E'],
  ['S','F','C','S'],
  ['A','D','E','E']
]
  • word = “ABCCED”, -> returns true,
  • word = “SEE”, -> returns true,
  • word = “ABCB”, -> returns false.

Subscribe to see which companies asked this question.

就是在一个矩阵字符串中,判断它能不能生成目标字符串。在矩阵中生成的目标字符串必须是连接的,是水平或者是竖直方向上连接。

代码实现

法一:最开始我是用的是广度优先。广度优先有个不好的地方,就是不好区别路径。

比如在这种情况下识别路径就很困难:

["ABCE","SFES","ADEE"]
"ABCESEEEFS"

我用BFS fail的代码是:

class Solution {
public:
    bool exist(vector<vector<char>>& board, string word) {
        int m = board.size(), n = m?board[0].size():0;
        bool res = false;
        if(!word.size()) return true;  
        if(!m || !n) return false;

        int loc[] = {-1, 0, 1, 0, 0, 1, 0, -1};

        for(int i = 0; i < m; i++) {
            for(int j = 0; j < n; j++) {
                if(board[i][j] == word[0]) {
                    vector<vector<bool>> visited(m, vector<bool>(n, false));
                    queue<pair<int, int>> que;
                    que.push(make_pair(i, j));
                    int cnt = 0;
                    visited[i][j] = true;
                    while(!que.empty() && cnt < word.size()) {
                        int sz = que.size();
                        for(int p = 0; p < sz; p++) {
                            int r = que.front().first, c = que.front().second;
                            que.pop();

                            if(board[r][c] == word[cnt]) {
                                visited[r][c] = true;
                                if(cnt + 1 == word.size()) return true;
                            for(int k = 0; k < 4; k++) 
                                if(r + loc[k] >= 0 && r + loc[k] < m && c + loc[k+4] >= 0 && c + loc[k+4] < n && !visited[r+loc[k]][c+loc[k+4]])
                                    que.push(make_pair(r+loc[k], c+loc[k+4]));
                            }
                        }
                        cnt++;

                    }
                    // if(cnt == word.size()) res = true;
                }
            }    
        }

        return res;
    }
};

法二:是用回溯,答案是正确的,但是超时了。看来我的回溯效率不高。以下代码是有错误的,没有经过合理的剪枝。我们应该在找到答案以后,把别的过程也终止的。

class Solution {
public:
    int loc[8] = {-1, 0, 1, 0, 0, 1, 0, -1};

    void judge(bool &res, vector<vector<char>>& board, string word, int& cnt, vector<vector<bool>>& vis, int m, int n, int r, int c) {
        if(cnt == word.size()) {
            res = true; return;
        }
        for(int k = 0; k < 4; k++) {
            if(r + loc[k] >= 0 && r + loc[k] < m && c + loc[k+4] >= 0 && c + loc[k+4] < n && !vis[r+loc[k]][c+loc[k+4]]) {
                if(board[r+loc[k]][c+loc[k+4]] == word[cnt]) {
                    vis[r+loc[k]][c+loc[k+4]] = true;  cnt++;
                    judge(res, board, word, cnt, vis, m, n, r + loc[k], c + loc[k+4]);
                    vis[r+loc[k]][c+loc[k+4]] = false; cnt--;
                }
            }
        }    
    }

    bool exist(vector<vector<char>>& board, string word) {
        int m = board.size(), n = m?board[0].size():0;
        bool res = false;
        if(!word.size()) return true;  
        if(!m || !n) return false;
        for(int i = 0; i < m; i++) {
            for(int j = 0; j < n; j++) {
                if(board[i][j] == word[0]) {
                    vector<vector<bool>> visited(m, vector<bool>(n, false));
                    visited[i][j] = true;
                    int cnt = 1;
                    judge(res, board, word, cnt, visited, m, n, i, j);
                }
            }    
        }

        return res;
    }
};

回溯的正确解法的代码为:

class Solution {
public:
    int loc[8] = {-1, 0, 1, 0, 0, 1, 0, -1};

    void judge(bool &res, vector<vector<char>>& board, string word, int& cnt, vector<vector<bool>>& vis, int m, int n, int r, int c) {
        if(cnt == word.size()) {
            res = true; return;
        }
        for(int k = 0; k < 4; k++) {
            if(res) return;
            if(r + loc[k] >= 0 && r + loc[k] < m && c + loc[k+4] >= 0 && c + loc[k+4] < n && !vis[r+loc[k]][c+loc[k+4]]) {
                if(res) return;
                if(board[r+loc[k]][c+loc[k+4]] == word[cnt]) {
                    if(res) return;
                    vis[r+loc[k]][c+loc[k+4]] = true;  cnt++;
                    judge(res, board, word, cnt, vis, m, n, r + loc[k], c + loc[k+4]);
                    vis[r+loc[k]][c+loc[k+4]] = false; cnt--;
                }
            }
        }    
    }

    bool exist(vector<vector<char>>& board, string word) {
        int m = board.size(), n = m?board[0].size():0;
        bool res = false;
        if(!word.size()) return true;  
        if(!m || !n) return false;
        for(int i = 0; i < m; i++) {
            for(int j = 0; j < n; j++) {
                if(board[i][j] == word[0]) {
                    vector<vector<bool>> visited(m, vector<bool>(n, false));
                    visited[i][j] = true;
                    int cnt = 1;
                    judge(res, board, word, cnt, visited, m, n, i, j);
                }
            }    
        }

        return res;
    }
};

法三:是用DFS,速度比回溯慢一些。

class Solution {
public:
    int loc[8] = {-1, 0, 1, 0, 0, 1, 0, -1};
    __inline vector<vector<bool>> set_flag(vector<vector<bool>> vis, int i, int j) {
        vis[i][j] = true;
        return vis;
    }

    __inline void judge(bool &res, vector<vector<char>>& board, string word, int cnt, vector<vector<bool>> vis, int m, int n, int r, int c) {
        if(cnt == word.size()) {
            res = true; return;
        }
        for(int k = 0; k < 4; k++) {
            if(res) return;
            if(r + loc[k] >= 0 && r + loc[k] < m && c + loc[k+4] >= 0 && c + loc[k+4] < n && !vis[r+loc[k]][c+loc[k+4]]) {
                if(res) return;
                if(board[r+loc[k]][c+loc[k+4]] == word[cnt]) {
                    if(res) return;
                    judge(res, board, word, cnt+1, set_flag(vis, r + loc[k], c + loc[k+4]), m, n, r + loc[k], c + loc[k+4]);
                }
            }
        }    
    }

    bool exist(vector<vector<char>>& board, string word) {
        int m = board.size(), n = m?board[0].size():0;
        bool res = false;
        if(!word.size()) return true;  
        if(!m || !n) return false;
        for(int i = 0; i < m; i++) {
            for(int j = 0; j < n; j++) {
                if(board[i][j] == word[0]) {
                    vector<vector<bool>> visited(m, vector<bool>(n, false));
                    visited[i][j] = true;
                    int cnt = 1;
                    judge(res, board, word, cnt, visited, m, n, i, j);
                }
            }    
        }

        return res;
    }
};

513. Find Bottom Left Tree Value

题目描述

Given a binary tree, find the leftmost value in the last row of the tree.

Example 1:

Input:

    2
   / \
  1   3

Output:
1

Example 2:

Input:

        1
       / \
      2   3
     /   / \
    4   5   6
       /
      7

Output:
7

Note: You may assume the tree (i.e., the given root node) is not NULL.

这道题目是求一棵树最后一行最左边的元素。

我一开始计算成了最高的左子树叶子了。

开始的时候代码是:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int findBottomLeftValue(TreeNode* root) {
        int res = root->val;
        queue<pair<TreeNode*, bool>> t;
        t.push(make_pair(root, true));
        while(!t.empty()) {
            int size = t.size();
            for(int i = 0; i < size; i++) {
                TreeNode *tmp = t.front().first;
                bool flg = t.front().second;
                t.pop();
                if(!tmp->left && !tmp->right && flg)  res = tmp->val;
                if(tmp->right)  t.push(make_pair(tmp->right, false));
                if(tmp->left)   t.push(make_pair(tmp->left, true));
            }    
        }
        return res;
    }
};

代码实现

AC的代码:非常简单的一道题目。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int findBottomLeftValue(TreeNode* root) {
        int res = root->val;
        queue<TreeNode*> t;
        t.push(root);
        while(!t.empty()) {
            int size = t.size();
            for(int i = 0; i < size; i++) {
                TreeNode *tmp = t.front();
                t.pop();
                if(!tmp->left && !tmp->right)  res = tmp->val;
                if(tmp->right)  t.push(make_pair(tmp->right, false));
                if(tmp->left)   t.push(make_pair(tmp->left, true));
            }    
        }
        return res;
    }
};

110. Balanced Binary Tree

题目描述

Given a binary tree, determine if it is height-balanced.

For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.

代码实现

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int compareBalance(TreeNode* root) {
        if(!root) return 0;
        int l1 = compareBalance(root->left);
        int r1 = compareBalance(root->right);
        if(l1 == -1 || r1 == -1 || abs(l1 - r1) > 1) return -1; 
        return max(l1, r1) + 1;
    }

    bool isBalanced(TreeNode* root) {
        return compareBalance(root) != -1;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值