79、岛屿的最大面积
class Solution {
public int maxAreaOfIsland(int[][] grid) {
int res = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
if (grid[i][j] == 1) {
res = Math.max(res, dfs(i, j, grid));
}
}
}
return res;
}
private int dfs(int i, int j, int[][] grid) {
if (i < 0 || j < 0 || i >= grid.length || j >= grid[i].length || grid[i][j] == 0) {
return 0;
}
grid[i][j] = 0;
int num = 1;
num += dfs(i + 1, j, grid);
num += dfs(i - 1, j, grid);
num += dfs(i, j + 1, grid);
num += dfs(i, j - 1, grid);
return num;
}
}
标准dfs题,值得注意的是dfs里面要设置标记位置,也就是沉岛,遍历到该位置就设置为0,num++,这样之后的就不会出错和重复计算了
80、回文链表
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {
ListNode fast = head;
ListNode slow = head;
ListNode pre = null;
// 找到中间节点并反转前半部分
while (fast != null && fast.next != null) {
fast = fast.next.next;
ListNode temp = slow.next;
slow.next = pre;
pre = slow;
slow = temp;
}
// 如果链表长度为奇数,slow现在指向中间节点,我们需要跳过它
// 当fast不是null时说明有奇数个节点
if (fast != null) {
slow = slow.next;
}
// 比较前半部分和后半部分
while (pre != null && slow != null) {
if (pre.val != slow.val) {
return false;
}
pre = pre.next;
slow = slow.next;
}
return true;
}
}
该题最显然的做法是找到中点然后将左半部分反转然后比较,上述代码做到了边反转边移动,然后分析链表长度问题,最后比较两部分
81、买卖股票的最佳时机II
class Solution {
public int maxProfit(int[] prices) {
int profit = 0;
for (int i = 1; i < prices.length; i++) {
int tmp = prices[i] - prices[i - 1];
if (tmp > 0) profit += tmp;
}
return profit;
}
}
该题采用贪心算法,意思是第二天比第一天多就卖,否则就不卖,当然套之前的dp状态模板也是能写的就是很麻烦
82、乘积最大子数组
class Solution {
public int maxProduct(int[] nums) {
if(nums.length==0){
return 0;
}
int ans=nums[0];
int[] maxDp=new int[nums.length];
int[] minDp=new int[nums.length];
maxDp[0]=nums[0];minDp[0]=nums[0];
for(int i=1;i<nums.length;i++){
maxDp[i]=Math.max(nums[i],Math.max((maxDp[i-1]*nums[i]),minDp[i-1]*nums[i]));
minDp[i]=Math.min(nums[i],Math.min((maxDp[i-1]*nums[i]),minDp[i-1]*nums[i]));
ans=Math.max(ans,maxDp[i]);
}
return ans;
}
}
动态规划问题:维护两个DP数组,以i下标结尾的最大乘积和最小乘积,分析好状态转移方程
比较三个值,更新maxDP和minDP,更新ans
83、最大数
class Solution {
public String largestNumber(int[] nums) {
String[] strs = new String[nums.length];
for (int i = 0; i < nums.length; i++)
strs[i] = String.valueOf(nums[i]);
Arrays.sort(strs, (x, y) -> (y + x).compareTo(x + y));
if (strs[0].equals("0"))
return "0";
StringBuilder res = new StringBuilder();
for (String s : strs)
res.append(s);
return res.toString();
}
}
作者Leetcode:Krahets
给出贪心策略,然后排序数组,最后拼接
84、多数元素
public class Solution {
public int majorityElement(int[] nums) {
int count = 0, candidate = 0;
for (int num : nums) {
if (count == 0) {
candidate = num;
count = 1;
} else if (num == candidate) {
count++;
} else {
count--;
}
}
return candidate;
}
}
遍历数组的同时更新数据,返回结果
85、不同路径
简单DP,走到该位置的时候,如果不是最上方或者最左方,则一定是从上方或者左方更新而来
class Solution {
public int uniquePaths(int m, int n) {
int[][] dp=new int[m+1][n+1];//dp数组代表走到该位置有多少条路径
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(i<=1||j<=1){
dp[i][j]=1;
}else{
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
}
}
return dp[m][n];
}
}