フラッドフィルアルゴリズムによる領域の囲い込みと最長連続シーケンス探索

問題1: フラッドフィルを用いた領域の囲い込み

二次元グリッドが与えられ、各セルは'X'または'O'で構成されます。境界に接続されていない'O'の領域を特定し、それらを'X'に変換する必要があります。境界に隣接する'O'は変換せずに保持します。

アプローチ: 深さ優先探索(DFS)を活用し、境界上の'O'から接続された領域を一時マークで識別します。その後、マークされていない内部の'O'を'X'に変換し、一時マークを元の'O'に戻します。

class Solution {
public:
    void solve(vector<vector<char>>& grid) {
        if(grid.empty()) return;
        int rows = grid.size();
        int cols = grid[0].size();
        vector<pair<int, int>> directions = {{-1,0}, {1,0}, {0,-1}, {0,1}};
        
        for(int r = 0; r < rows; r++) {
            markRegion(grid, r, 0, directions);
            markRegion(grid, r, cols-1, directions);
        }
        for(int c = 0; c < cols; c++) {
            markRegion(grid, 0, c, directions);
            markRegion(grid, rows-1, c, directions);
        }
        
        for(int r = 0; r < rows; r++) {
            for(int c = 0; c < cols; c++) {
                if(grid[r][c] == 'O') grid[r][c] = 'X';
                else if(grid[r][c] == 'T') grid[r][c] = 'O';
            }
        }
    }
    
    void markRegion(vector<vector<char>>& grid, int r, int c, vector<pair<int, int>>& dirs) {
        if(r < 0 || c < 0 || r >= grid.size() || c >= grid[0].size() || grid[r][c] != 'O') 
            return;
        grid[r][c] = 'T';
        for(auto& d : dirs) {
            int nr = r + d.first;
            int nc = c + d.second;
            markRegion(grid, nr, nc, dirs);
        }
    }
};

問題2: 最長連続数値シーケンスの探索

整数配列が与えられた時、隣接する数値が連続する最長シーケンスの長さを求めます。計算量はO(n)である必要があります。

アプローチ: ハッシュセットを使用して効率的な検索を実現します。各数値について、前後の連続する数値が存在するかどうかをチェックし、最長シーケンスを追跡します。

class SequenceFinder {
public:
    int findLongestSequence(vector<int>& nums) {
        if(nums.size() <= 1) return nums.size();
        unordered_set<int> numSet(nums.begin(), nums.end());
        int maxSequence = 1;
        
        for(int num : nums) {
            if(numSet.find(num) == numSet.end()) continue;
            
            int left = num;
            while(numSet.find(left-1) != numSet.end()) {
                numSet.erase(left-1);
                left--;
            }
            
            int right = num;
            while(numSet.find(right+1) != numSet.end()) {
                numSet.erase(right+1);
                right++;
            }
            
            maxSequence = max(maxSequence, right - left + 1);
        }
        return maxSequence;
    }
};

タグ: フラッドフィル 深さ優先探索 ハッシュテーブル 連続シーケンス

7月28日 16:43 投稿