Algorithm-week6

来源:互联网 发布:mac photoshop 破解版 编辑:程序博客网 时间:2024/06/09 20:20

Week6

Program--Medium--419. Battleships in a Board

Given an 2D board, count how many battleships are in it. The battleships are represented with 'X's, empty slots are represented with '.'s. You may assume the following rules:

  • You receive a valid board, made of only battleships or empty slots.
  • Battleships can only be placed horizontally or vertically. In other words, they can only be made of the shape 1xN (1 row, N columns) or Nx1 (N rows, 1 column), where N can be of any size.
  • At least one horizontal or vertical cell separates between two battleships - there are no adjacent battleships.

Example:

X..X...X...X
In the above board there are 2 battleships.

Invalid Example:

...XXXXX...X
This is an invalid board that you will not receive - as battleships will always have a cell separating between them.

Follow up:
Could you do it in one-pass, using only O(1) extra memory and without modifying the value of the board?

题目解析:

这是一道类似与图的连通问题,在一张矩形的图中,只有相邻为X的点才是连通的,为"."的点则是不通的,问题就可以转化为有多少个连通集合,且连通的方向只有上下或者左右,为寻找同路提供了方便。在这里,我用一种消除的方法,从左到右,从上往下,在找到一个X后,水平或者垂直搜索,找与之连通的其他X,边找边把他们变为“.”,将这个连通集合消除变为“.”,表示这艘船以及被找过,同时count++。做到最后,消除所有X后,count的值就记录了我们消除的船的个数。

代码:

class Solution {public:    int countBattleships(vector<vector<char>>& map) {        int count = 0;        for (int i = 0; i < map.size(); i++) {            for (int j = 0; j < map[i].size(); j++) {                if (map[i][j] == 'X') {                    map[i][j] = '.';                    if (j + 1 < map[i].size()) {                        if (map[i][j + 1] == 'X') {                            findShip(map, i, j + 1, "hor");                        }                    }                    if (i + 1 < map.size())  {                        if (map[i + 1][j] == 'X')                            findShip(map, i + 1, j, "ver");                    }                    count++;                }            }        }        return count;    }        void findShip(vector<vector<char>> &map, int i, int j, string dir) {        if (dir == "ver") {            while(i < map.size() && map[i][j] == 'X') {                map[i][j] = '.';                i++;            }        } else {            while(j < map[i].size() && map[i][j] == 'X') {                map[i][j] = '.';                j++;            }        }    }}; 

Program--Medium--64. Minimum Path Sum

Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.

Note: You can only move either down or right at any point in time.

题目解析:

这个问题类似于图算法中的最小路径的寻找,那么,解决方法就很直观了,直接利用Dijkstra算法即可。不过细节还是值得注意的,这主要体现在各种变量的数据结构上。对于Dijkstra算法,我们需要维护从起点到点u的路径长dis[u],由于直接输出右下角的dis,所以我们不需要维护当前点的前一个点的记录变量prev,所以重点就只在dis和队列的数据结构上。

1.在这里我用vector<vector<int>>dis来存储距离信息,通过Dijkstra算法,遍历整个邻接矩阵,就可以得到右下角点的最短距离。

2.算法按最小值排序的需求我用优先队列来实现,我没有事先把所有点的值放入队列中进行排序,只有当下一个点满足判断要求才加入,这样就避免那些值为无穷大的被加进去,我们是不需要维护他们的大小关系的,因为他们永远位于队列之后。当一个点的距离有无限变成更小值时,它一定会被加入队列,避免有的点不会入队。

代码:

class Solution {public:    struct node {        int i;        int j;        int val;        node(int r, int c, int v) {            i = r;            j = c;            val = v;        };        friend bool operator < (node a, node b) {                  return a.val > b.val;    //重载小于号使得小的先出队列              }    };        int minPathSum(vector<vector<int>>& grid) {        vector<vector<int>> dis(grid);        priority_queue<node> Queue;        for(int i = 0; i < grid.size(); i++) {            for (int j = 0; j < grid[i].size(); j++) {                int temp;                if (!i && !j) {                    dis[i][j] = grid[0][0];                } else {                    dis[i][j] = INT_MAX;                }            }        }        Queue.push(node(0,0,dis[0][0]));        while(Queue.size()) {            node temp = Queue.top();            Queue.pop();            int r = temp.i, c = temp.j;            if (r+1<grid.size()) {                if (dis[r+1][c] > dis[r][c] + grid[r+1][c]) {                    dis[r+1][c] = dis[r][c] + grid[r+1][c];                    Queue.push(node(r+1,c,dis[r+1][c]));                }            }            if (c+1<grid[0].size()) {                if (dis[r][c+1] > dis[r][c] + grid[r][c+1]) {                    dis[r][c+1] = dis[r][c] + grid[r][c+1];                    Queue.push(node(r,c+1,dis[r][c+1]));                }            }        }        return dis[grid.size()-1][grid[0].size()-1];    }};

To be Continued...



原创粉丝点击