• 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;
    }

  • 相关阅读:
    timescaledb 几个方便的api
    k8s PersistentVolume hostpath 简单使用
    timescaledb replication 使用
    timesacledb 测试demo数据运行
    conan c&&c++ 包管理工具使用
    graphql-yoga interface && union 使用
    JFrog Artifactory CE c&&c++ 包管理工具
    graphcool-framework 一个基于graphql的后端开发框架
    graphql-yoga 项目简单使用&&集成docker
    nsq 安装试用
  • 原文地址:https://www.cnblogs.com/niuyourou/p/16284071.html
Copyright © 2020-2023  润新知