这题与反转链表Ⅰ类似嘛,不过多了个最开始的结点(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;
}
}