LeetCode反转链表Ⅱ,岛屿的最大面积(dfs)

在这里插入图片描述这题与反转链表Ⅰ类似嘛,不过多了个最开始的结点(first)和保存开始反转前的结点(start)和结束的反转后的结点(eend),以及反转后最后个结点(end)。其他的与第二题,反转链表Ⅰ一样,将需要反转的部分当成前后都是null。
在这里插入图片描述
这里用了迭代的方式,递归思路也是一样的(比较懒就不写了)

class Solution {
    public ListNode reverseBetween(ListNode head, int m, int n) {
        ListNode first = head;
        for(int i=0;i<m-2&&head.next!=null;i++){
            head = head.next;
        }
        if(head==null){
            return first;
        }
        ListNode start = head;
        head = m==1?head:head.next;
        ListNode end = null;
        ListNode eend = head;
        ListNode pre = null;ListNode curr = head;
        for(int i=0;i<n-m+1;i++){
            if(curr == null){
                return pre;
            }
            ListNode temp;
            if(i==n-m){
                end = curr.next;
                temp = null;
            }
            else{
              temp  = curr.next;
            }
            curr.next = pre;
            pre = curr;
            curr = temp;
        }
        if(m!=1){
            start.next = pre;//等于1时,如果执行了相当于成了一个循环链表了
        }
        eend.next = end;
        return m==1?pre:first;

    }
}

在这里插入图片描述
这道题用深度优先倒是很好做(广度优先也阔以),每个点都探一探。不过这样就会有很多重复的计算,可以用一个Set结构存储一下已经探索过的地方。

class Solution {
    int[][] grid;
    Set<Coordinate> set;
    int m,n;
    public int maxAreaOfIsland(int[][] grid) {
        this.grid = grid;
        m = grid.length;
        if(m==0){
            return 0;
        }
        n = grid[0].length;
        if(n==0){
            return 0;
        }
        set = new HashSet<>();
        int max = 0;
        for(int i =0;i<m;i++){
            for(int j=0;j<n;j++){
                Coordinate c = new Coordinate(j,i);
                if(!set.contains(c)){
                    if(grid[i][j]==1){
                        int temp = dfs(j,i,1);
                        max = temp>max?temp:max;
                    }
                    else{
                        set.add(c);
                    }
                }
            }
        }
        return max;
    }

    private int dfs(int x,int y,int ans){
        if(x==-1||x==n||y==-1||y==m){
            return ans-1;
        }
        Coordinate c = new Coordinate(x,y);
        if(set.contains(c)){
            return ans-1;
        }
        set.add(c);
        if(grid[y][x]==0){
            return ans-1;
        }
        ans+=dfs(x-1,y,1);
        ans+=dfs(x+1,y,1);
        ans +=dfs(x,y+1,1);
        ans+= dfs(x,y-1,1);
        return ans;
    }
}
class Coordinate{
    int x,y;
    public Coordinate(int x,int y){
        this.x = x;
        this.y = y;
    }

    @Override
    public boolean equals(Object obj) {
        if(obj==this){
            return true;
        }
        if(obj==null||obj.getClass()!=getClass()){
            return false;
        }
        Coordinate c = (Coordinate) obj;
        return c.x==x&&c.y==y;
    }

    @Override
    public int hashCode() {
        return Objects.hash(x,y);
    }
}

看了答案有一种沉岛思想还是挺妙的,将探索过的岛屿全部置0,防止重复计算且下次不用再计算同一个岛屿了,感觉这个思想有点妙啊。

class Solution {
    int[][] grid;
    int m,n;
    public int maxAreaOfIsland(int[][] grid) {
        this.grid = grid;
        m = grid.length;
        if(m==0){
            return 0;
        }
        n = grid[0].length;
        if(n==0){
            return 0;
        }
        int max = 0;
        for(int i =0;i<m;i++){
            for(int j=0;j<n;j++){
                if(grid[i][j]==1){
                    int temp = dfs(j,i,1);
                    max = temp>max?temp:max;
                }
            }
        }
        return max;
    }

    private int dfs(int x,int y,int ans){
        if(x==-1||x==n||y==-1||y==m||grid[y][x]==0){
            return ans-1;
        }
        grid[y][x] = 0;
        ans+=dfs(x-1,y,1);
        ans+=dfs(x+1,y,1);
        ans +=dfs(x,y+1,1);
        ans+= dfs(x,y-1,1);
        return ans;
    }
}
发布了18 篇原创文章 · 获赞 1 · 访问量 272

猜你喜欢

转载自blog.csdn.net/qq_38732834/article/details/105221717