4月22日 刷题报告 LC128-132

128. Longest Consecutive Sequence

Given an unsorted array of integers, find the length of the longest consecutive elements sequence.

Your algorithm should run in O(n) complexity.

Example:

Input: [100, 4, 200, 1, 3, 2]
Output: 4
Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4.

哈希,先把整个输入数组导入unordered_set(后面的测试证明比set更快),然后遍历数组。取 val = *hash.begin()遍历哈希表,两个while循环判断hash中是否存在val+i和val-i,存在则将他们从hash中删除。例如上面的例子中,先判断100,没有99/101,删除100,maxLen=1;val=4,3,2,1存在,删除,maxLen=4;val=200,不存在199/201,len=1<maxLen。这个做法必须依赖哈希,因为涉及到频繁的查找val+1/val-1是否存在。

int longestConsecutive(vector<int>& nums) {
    if (nums.size() == 0) {
        return 0;
    }
    unordered_set<int> hash(nums.begin(), nums.end());
    int bias, t, count, maxLen;
    maxLen = INT_MIN;
    for (int num : hash) {
        if (hash.find(num) == hash.end()) {
            continue;
        }
        bias = count = 1;
        while (true) {
            t = num + bias;
            if (hash.find(t) != hash.end()) {
                count += 1;
                bias += 1;
                hash.erase(t);
            }
            else
                break;
        }
        bias = 1;
        while (true) {
            t = num - bias;
            if (hash.find(t) != hash.end()) {
                count += 1;
                bias += 1;
                hash.erase(t);
            }
            else
                break;
        }
        maxLen = count > maxLen ? count : maxLen;
    }
    return maxLen;
}

129. Sum Root to Leaf Numbers

Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number.

An example is the root-to-leaf path 1->2->3 which represents the number 123.

Find the total sum of all root-to-leaf numbers.

Note: A leaf is a node with no children.

Example:

Input: [1,2,3]
    1
   / \
  2   3
Output: 25
Explanation:
The root-to-leaf path 1->2 represents the number 12.
The root-to-leaf path 1->3 represents the number 13.
Therefore, sum = 12 + 13 = 25.

一开始尝试bottom-up的顺序,结果要处理的情况比较多,麻烦。改用top-down,递归向下,每次将上面传下来的值乘以10再加上自身的值,当走到叶节点就将值加入res。

void getSum(TreeNode* root, int base, int& res) {
    base = base * 10 + root->val;
    if (!root->left && !root->right) {
        // leaf node! add the sum of this path to res
        res += base;
        return;
    }
    if (root->left) {
         getSum(root->left, base, res);
    }
    if (root->right) {
        getSum(root->right, base, res);
    }
}
int sumNumbers(TreeNode* root) {
    if (root == NULL) {
        return 0;
    }
    int res = 0;
    getSum(root, 0, res);
    return res;
}

130. Surrounded Regions

Given a 2D board containing 'X' and 'O' (the letter O), capture all regions surrounded by 'X'.

A region is captured by flipping all 'O's into 'X's in that surrounded region.

Example:

X X X X
X O O X
X X O X
X O X X

After running your function, the board should be:

X X X X
X X X X
X X X X
X O X X

Explanation:

Surrounded regions shouldn’t be on the border, which means that any 'O' on the border of the board are not flipped to 'X'. Any 'O' that is not on the border and it is not connected to an 'O' on the border will be flipped to 'X'. Two cells are connected if they are adjacent cells connected horizontally or vertically.

这道题用BFS查找所有不和边界连接的O的集合。一开始我的做法是遍历board,把所有的O找出来存储在一个set里,然后对于set中的每个点用BSF找到和它邻接的点,每次判断加入的点是否位于边界,位于边界则回头把邻接的这些点改成X,具体实现上可以用一个数组保存所有的这些邻接点,回头改成X的时候就不用再次遍历。这种做法显然不好,每次都需要4次if判断是否在边界上。更好的做法其实很简单,先不处理内部要改的O,反而先来处理边界上不需要改的O。先遍历board中位于边界的点,如果是O则从他们开始进行BFS,这些和边界相连接的O是不用改成X的,所以暂时将他们标记为B。最后遍历一次board,遇到O则说明他不和边界连接,因此把他们改成X,遇到B说明他和边界连接并且之前由O变过来,把他们改回O即可。

void bfsBoundary(vector<vector<char> >& board, int w, int l)
{
    int width = (int)board.size();
    int length = (int)board[0].size();
    deque<pair<int, int>> q;
    q.push_back(make_pair(w, l));
    board[w][l] = 'B';
    while (!q.empty()) {
        pair<int, int> cur = q.front();
        q.pop_front();
        pair<int, int> adjs[4] = {
            {cur.first-1, cur.second},
            {cur.first+1, cur.second},
            {cur.first, cur.second-1},
            {cur.first, cur.second+1}
        };
        for (int i = 0; i < 4; ++i)
        {
            int adjW = adjs[i].first;
            int adjL = adjs[i].second;
            if ((adjW >= 0) && (adjW < width) && (adjL >= 0) && (adjL < length) && (board[adjW][adjL] == 'O')) {
                q.push_back(make_pair(adjW, adjL));
                board[adjW][adjL] = 'B';
            }
        }
    }
}

void solve(vector<vector<char> > &board) {
    // Use BFS starting from 'O’s on the boundary and mark them as ‘B’, then iterate over the whole board and mark ‘O’ as ‘X’ and ‘B’ as ‘O’.
    
    int width = (int)board.size();
    if (width == 0) //Add this to prevent run-time error!
        return;
    int length = (int)board[0].size();
    if  (length == 0) // Add this to prevent run-time error!
        return;
    
    for (int i = 0; i < length; ++i)
    {
        if (board[0][i] == 'O')
            bfsBoundary(board, 0, i);
        
        if (board[width-1][i] == 'O')
            bfsBoundary(board, width-1, i);
    }
    
    for (int i = 0; i < width; ++i)
    {
        if (board[i][0] == 'O')
            bfsBoundary(board, i, 0);
        if (board[i][length-1] == 'O')
            bfsBoundary(board, i, length-1);
    }
    
    for (int i = 0; i < width; ++i)
    {
        for (int j = 0; j < length; ++j)
        {
            if (board[i][j] == 'O')
                board[i][j] = 'X';
            else if (board[i][j] == 'B')
                board[i][j] = 'O';
        }
    }
}
LC131和132另外单独记录。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值