第一题
295. 数据流的中位数
本题我们是求解给定数组的中位数。且由于需要随时给数组添加元素,所以我们要求解该动态数组的中位数,所以本题最关键的就是维护数组在添加元素之后保持有序的排序,这样就能很快的求解中位数;
解法:我们使用大小堆来维护数据流的中位数
如上图所示,我们将当前数组从中间分为两部分,左边部分的数据放入到大根堆,右边数据放入到小根堆,且两个堆的数据长度只有两种情况,要么两的个堆里面数据相同,要么左堆的长度比右堆的长度多一;
接下来就是分类讨论添加数据的详细情况:
步骤一:
定义大根堆的堆顶元素为x,里面元素的个数为m;小根堆堆顶的元素为y,里面元素的个数为n;
步骤二:
当m等于n时:
添加元素nums小于等于x或者当前两个堆都为空时,nums元素直接进入到左边大根堆;添加元素nums大于x时,nums元素首先进入到右边小根堆,然后将右边小根堆的堆顶元素放入到左边大根堆中;
步骤三:
当m等于n+1时:
添加元素nums大于x时,nums元素直接进入到右边小根堆;
添加元素nums小于等于x时,nums元素首先进入到左边大根堆,然后将左边大根堆的堆顶元素放入到右边小根堆中;
步骤四:
根据情况求取该数组的中位数;
综上所述,代码如下:
class MedianFinder {PriorityQueue<Integer> left;PriorityQueue<Integer> right;public MedianFinder() {left = new PriorityQueue<Integer>((a,b) -> b - a);right = new PriorityQueue<Integer>((a,b) -> a - b);}public void addNum(int num) {if(left.size() == right.size()){if(left.isEmpty() || num <= left.peek()){left.offer(num);}else{right.offer(num);left.offer(right.poll());}}else{if(num <= left.peek()){left.offer(num);right.offer(left.poll());}else{right.offer(num);}}}public double findMedian() {if(left.size() == right.size()) return (left.peek() +right.peek())/2.0;else return left.peek();} }/*** Your MedianFinder object will be instantiated and called as such:* MedianFinder obj = new MedianFinder();* obj.addNum(num);* double param_2 = obj.findMedian();*/
第二题
733. 图像渲染
解法:bfs层序遍历
层序遍历如下所示:
假设当前的当前位置如下所示:
第二部就是找到其相邻的:
第三部就是找到第二部中相邻的:
依次类推;
本题的解题步骤如下:
综上所述,代码如下:
步骤一:
创建一个队列,将当前的元素放入到队列里面,并将元素改变颜色;
步骤二:
将队列中的元素先拿出来一个,分析出该元素的坐标,采用象限数组的方式来遍历该元素的上下左右四个位置的元素;
即如下所示:
如果该被遍历到的元素满足条件就将该元素放入到队列中,并将该元素按要求变色;
步骤三:就这样一一拿出队列中的元素,一直重复,直到队列为空为止;
class Solution {//象限坐标数组int[] dx = {0,0,1,-1};int[] dy = {1,-1,0,0};public int[][] floodFill(int[][] image, int sr, int sc, int color) {int prev = image[sr][sc];//统计刚开始的颜色if(prev == color) return image;//处理边界情况Queue<int[]> q = new LinkedList<>();q.add(new int[]{sr,sc});int m = image.length,n = image[0].length;while(!q.isEmpty()){int[] t = q.poll();int a = t[0],b=t[1];//取出收个点的x,y周坐标//该坐标的上下左右四个点,用向量数组坐标的方法来展示image[a][b] = color;for(int i = 0;i<4;i++){int x = a + dx[i],y = b + dy[i];if(x >= 0 && x <m && y >= 0 && y < n && image[x][y] == prev){q.add(new int[]{x,y});}}}return image;} }
第三题
200. 岛屿数量
示例一:
示例二:
解法:本题采用bfs层序遍历的方法,同时采用象限数组小技巧;
本题重新定义一个长度宽度与原题相似的布尔数组vis,每当遍历到一个元素且满足该题意要求是,将vis数组里面相对应位置的元素定义为true,这样在遍历的时候防治该元素被二次遍历;
总体的解题思路如上题故事,代码如下所示:
class Solution {//象限坐标数组int[] dx = {0,0,1,-1};int[] dy = {1,-1,0,0};boolean[][] vis = new boolean[301][301];int m,n;public int numIslands(char[][] grid) {m = grid.length;n = grid[0].length;int ret = 0;for(int i = 0;i < m ;i++){for(int j = 0;j < n ;j++){if(grid[i][j] == '1' && !vis[i][j]){ret++;bfs(grid,i,j);}}}return ret;}public void bfs(char[][] grid,int i,int j){Queue<int[]> q = new LinkedList<>();q.add(new int[]{i,j});vis[i][j] = true;while(!q.isEmpty()){int[] t = q.poll();int a = t[0],b = t[1];for(int s = 0;s < 4;s++){int x = a +dx[s],y = b + dy[s];if(x >= 0 && x <m && y >= 0 && y < n && grid[x][y] == '1' && !vis[x][y]){q.add(new int[]{x,y});vis[x][y] = true;}}}} }
ps:本次的内容就到这里了,如果对你有所帮助的话就请一一键三连哦!!!