Leetcode 934 最短的桥 DFS标记+BFS寻址

 

  C:

// 队列与栈
struct Node
{
    int val;
    int depth;
    struct Node *next;
    struct Node *pre;
};

struct Queue
{
    struct Node *head;
    struct Node *last;
    int len;
};

struct Queue *initQueue()
{
    struct Queue *queue = (struct Queue *)malloc(sizeof(struct Queue));
    struct Node *head = (struct Node *)malloc(sizeof(struct Node));
    struct Node *last = (struct Node *)malloc(sizeof(struct Node));
    head->next = last;
    head->pre = NULL;
    last->pre = head;
    last->next = NULL;
    queue->head = head;
    queue->last = last;
    queue->len = 0;
    return queue;
};

void push(struct Queue *queue, int val, int depth)
{
    struct Node *node = (struct Node *)malloc(sizeof(struct Node));
    node->val = val;
    node->depth = depth;
    node->next = queue->head->next;
    node->pre = queue->head;
    node->next->pre = node;
    queue->head->next = node;
    queue->len++;
}

struct Node *pop(struct Queue *queue)
{
    if (queue->len == 0)
        return NULL;
    struct Node *node = queue->head->next;
    node->next->pre = queue->head;
    queue->head->next = node->next;
    queue->len--;
    return node;
}

void add(struct Queue *queue, int val, int depth)
{
    struct Node *node = (struct Node *)malloc(sizeof(struct Node));
    node->val = val;
    node->depth = depth;
    node->next = queue->last;
    node->pre = queue->last->pre;
    node->pre->next = node;
    queue->last->pre = node;
    queue->len++;
}

void freeQueue(struct Queue *queue)
{
    struct Node *node = queue->head;
    while (node != NULL)
    {
        struct Node *next = node->next;
        free(node);
        node = next;
    }
    free(queue);
}

// 获取相邻元素
struct Queue *getAround(int **grid, int gridSize, int *gridColSize, int point)
{
    struct Queue *queue = initQueue();
    int x = point / (*gridColSize), y = point % (*gridColSize);
    if (x > 0)
    {
        push(queue, (x - 1) * (*gridColSize) + y, 0);
    }
    if (x < gridSize - 1)
    {
        push(queue, (x + 1) * (*gridColSize) + y, 0);
    }
    if (y > 0)
    {
        push(queue, x * (*gridColSize) + y - 1, 0);
    }
    if (y < (*gridColSize) - 1)
    {
        push(queue, x * (*gridColSize) + y + 1, 0);
    }
    return queue;
}

// 标记起点岛屿
int *markSource(int **grid, int gridSize, int *gridColSize, int point)
{
    int *marked = (int *)malloc(sizeof(int) * gridSize * (*gridColSize));
    memset(marked, 0, sizeof(int) * gridSize * (*gridColSize));
    struct Queue *stack = initQueue();
    push(stack, point, 0);
    while (stack->len > 0)
    {
        struct Node *node = pop(stack);
        int val = node->val;
        marked[val] = 2;
        struct Queue *arounds = getAround(grid, gridSize, gridColSize, val);
        struct Node *aroundI = pop(arounds);
        while (aroundI != NULL)
        {
            int currP = aroundI->val;
            int currX = currP / (*gridColSize), currY = currP % (*gridColSize);
            if (grid[currX][currY] == 1 && marked[currP] != 2)
            {
                marked[currP] = 2;
                push(stack, currP, 0);
            }
            free(aroundI);
            aroundI = pop(arounds);
        }
        freeQueue(arounds);
    }
    freeQueue(stack);
    return marked;
}

// 标记起点与终点岛屿
int *markAll(int **grid, int gridSize, int *gridColSize)
{
    int *marked = NULL;
    for (int i = 0; i < gridSize; i++)
    {
        for (int j = 0; j < *gridColSize; j++)
        {
            if (grid[i][j] == 1)
            {
                marked = markSource(grid, gridSize, gridColSize, i * (*gridColSize) + j);
                break;
            }
        }
        if (marked != NULL)
            break;
    }
    for (int i = 0; i < gridSize; i++)
    {
        for (int j = 0; j < *gridColSize; j++)
        {
            int point = i * (*gridColSize) + j;
            if (grid[i][j] == 1 && marked[point] != 2)
                marked[point] = 1;
        }
    }
    return marked;
}

// 由起点岛屿的所有元素开始 BFS
int shortestBridge(int **grid, int gridSize, int *gridColSize)
{
    int *marked = markAll(grid, gridSize, gridColSize);
    int *visit = malloc(sizeof(int) * gridSize * (*gridColSize));
    memset(visit, 0, sizeof(int) * gridSize * (*gridColSize));
    struct Queue *begins = initQueue();
    for (int i = 0; i < gridSize; i++)
    {
        for (int j = 0; j < *gridColSize; j++)
        {
            int p = i * (*gridColSize) + j;
            if (marked[p] == 1)
                add(begins, p, 0);
        }
    }
    // BFS 搜索
    while (begins->len > 0)
    {
        struct Node *node = pop(begins);
        if (marked[node->val] == 2)
            return node->depth - 1;
        struct Queue *arounds = getAround(grid, gridSize, gridColSize, node->val);
        while (arounds->len > 0)
        {
            struct Node *around = pop(arounds);
            int ap = around->val;
            if (marked[ap] != 1 && visit[ap] != 1)
            {
                // 已路过路径剪枝
                visit[ap] = 1;
                add(begins, ap, node->depth + 1);
            }
        }
    }
    return -1;
}

  JAVA:

class Solution {
 public final int shortestBridge(int[][] grid) {
            int[][] marked = markAll(grid);
            Queue<Node> queue = new LinkedList<Node>();
            Set<Integer> set = new HashSet<Integer>();
            int xLen = grid.length, yLen = grid[0].length;
            for (int i = 0; i < xLen; i++) {
                for (int j = 0; j < yLen; j++) {
                    if (marked[i][j] == 1) queue.add(new Node(i, j, 0));
                    else if (marked[i][j] == 2) set.add(i * yLen + j);
                }
            }
            while (queue.size() > 0) {
                Node node = queue.poll();
                int point = node.x * yLen + node.y;
                if (set.contains(point)) return node.depth - 1;
                List<Integer> arounds = getAround(grid, node.x * yLen + node.y);
                for (int i = 0; i < arounds.size(); i++) {
                    int aroundI = arounds.get(i), aroundIX = aroundI / yLen, aroundIY = aroundI % yLen;
                    if (marked[aroundIX][aroundIY] == 1) continue;
                    queue.add(new Node(aroundIX, aroundIY, node.depth + 1));
                    marked[aroundIX][aroundIY] = 1;
                }
            }
            return -1;
        }

        private final int[][] markAll(int[][] grid) {
            int xLen = grid.length, yLen = grid[0].length;
            int[][] markSource = null;
            for (int i = 0; i < xLen; i++) {
                if (markSource != null) break;
                for (int j = 0; j < yLen; j++) {
                    if (grid[i][j] == 1) {
                        markSource = mark(grid, i * yLen + j);
                        break;
                    }
                }
            }
            for (int i = 0; i < xLen; i++) {
                for (int j = 0; j < yLen; j++) {
                    if (grid[i][j] == 1 && markSource[i][j] != 2) markSource[i][j] = 1;
                }
            }
            return markSource;
        }

        private final int[][] mark(int[][] grid, int point) {
            int xLen = grid.length, yLen = grid[0].length;
            int[][] marked = new int[xLen][yLen];
            Stack<Integer> stack = new Stack<Integer>();
            int x = point / yLen, y = point % yLen;
            marked[x][y] = 2;
            stack.push(point);
            while (stack.size() > 0) {
                int currPoint = stack.pop();
                List<Integer> around = getAround(grid, currPoint);
                for (int i = 0; i < around.size(); i++) {
                    int aroundI = around.get(i);
                    int xPoint = aroundI / yLen, yPoint = aroundI % yLen;
                    if (grid[xPoint][yPoint] == 1 && marked[xPoint][yPoint] == 0) {
                        marked[xPoint][yPoint] = 2;
                        stack.push(aroundI);
                    }
                }
            }
            return marked;
        }

        //获取四周元素的集合
        private final List<Integer> getAround(int[][] grid, int point) {
            List<Integer> aroundList = new ArrayList<Integer>();
            int xLen = grid.length, yLen = grid[0].length;
            int xPoint = point / yLen, yPoint = point % yLen;
            if (xPoint > 0) aroundList.add((xPoint - 1) * yLen + yPoint);
            if (xPoint < xLen - 1) aroundList.add((xPoint + 1) * yLen + yPoint);
            if (yPoint > 0) aroundList.add(xPoint * yLen + yPoint - 1);
            if (yPoint < yLen - 1) aroundList.add(xPoint * yLen + yPoint + 1);
            return aroundList;
        }

        private class Node {
            int x;
            int y;
            int depth;

            Node(int x, int y, int depth) {
                this.x = x;
                this.y = y;
                this.depth = depth;
            }
        }
}

  JS:

/**
 * @param {number[][]} grid
 * @return {number}
 */
var shortestBridge = function (grid) {
    let marked = markAll(grid);
    let begins = [], set = new Set();
    let xLen = grid.length, yLen = grid[0].length;
    for (let i = 0; i < xLen; i++) {
        for (let j = 0; j < yLen; j++) {
            if (marked[i][j] == 1) begins.push({val: i * yLen + j, depth: 0});
            else if (marked[i][j] == 2) set.add(i * yLen + j);
        }
    }
    while (begins.length > 0) {
        let begin = begins.shift();
        if (set.has(begin.val)) return parseInt(begin.depth) - 1;
        let arounds = getAround(grid, begin.val);
        for (let i = 0; i < arounds.length; i++) {
            let aroundP = arounds[i];
            let aroundX = parseInt(aroundP / yLen), aroundY = parseInt(aroundP % yLen);
            if (marked[aroundX][aroundY] != 1) {
                marked[aroundX][aroundY] = 1;
                begins.push({val: aroundP, depth: parseInt(begin.depth) + 1});
            }
        }
    }
    return null;
};

var markAll = function (grid) {
    let xLen = grid.length, yLen = grid[0].length, marked = null;
    for (let i = 0; i < xLen; i++) {
        for (let j = 0; j < yLen; j++) {
            if (grid[i][j] != 0) {
                marked = mark(grid, i * yLen + j);
                break;
            }
        }
        if (marked) break;
    }
    for (let i = 0; i < xLen; i++) {
        for (let j = 0; j < yLen; j++) {
            if (grid[i][j] == 1 && marked[i][j] != 2) marked[i][j] = 1;
        }
    }
    return marked;
}

var mark = function (grid, point) {
    let xLen = grid.length, yLen = grid[0].length, x = parseInt(point / yLen), y = parseInt(point % yLen);
    let marked = new Array(xLen);
    for (let i = 0; i < xLen; i++) {
        marked[i] = new Array(yLen);
        for (let j = 0; j < yLen; j++) marked[i][j] = parseInt(0);
    }
    let stack = [];
    stack.push(point);
    marked[x][y] = 2;
    while (stack.length > 0) {
        let currP = stack.pop();
        let arounds = getAround(grid, currP);
        for (let i = 0; i < arounds.length; i++) {
            let aroundP = arounds[i], aroundX = parseInt(aroundP / yLen), aroundY = parseInt(aroundP % yLen);
            if (grid[aroundX][aroundY] == 1 && marked[aroundX][aroundY] != 2) {
                marked[aroundX][aroundY] = 2;
                stack.push(aroundX * yLen + aroundY);
            }
        }
    }
    return marked;
}

var getAround = function (grid, point) {
    let re = [];
    let xLen = grid.length, yLen = grid[0].length, x = parseInt(point / yLen), y = parseInt(point % yLen);
    if (x > 0) re.push((x - 1) * yLen + y);
    if (x < xLen - 1) re.push((x + 1) * yLen + y);
    if (y > 0) re.push(x * yLen + y - 1);
    if (y < yLen - 1) re.push(x * yLen + y + 1);
    return re;
}

 

posted @ 2022-05-18 11:37  牛有肉  阅读(35)  评论(0编辑  收藏  举报