2021-08-23 力扣刷题笔记
题目描述
解题思路
一、733. 图像渲染
题目描述
解题思路
二、695. 岛屿的最大面积
题目描述
解题思路
三、11. 盛最多水的容器
题目描述
解题思路
四、15. 三数之和
题目描述
解题思路
五、20. 有效的括号
题目描述
解题思路
每日一题 1646. 获取生成数组中的最大值
题目描述
给你一个整数 n 。按下述规则生成一个长度为 n + 1 的数组 nums :
nums[0] = 0
nums[1] = 1
当 2 <= 2 * i <= n 时,nums[2 * i] = nums[i]
当 2 <= 2 * i + 1 <= n 时,nums[2 * i + 1] = nums[i] + nums[i + 1]
返回生成数组 nums 中的 最大值。
示例 1:
输入:n = 7
输出:3
解释:根据规则:
nums[0] = 0
nums[1] = 1
nums[(1 * 2) = 2] = nums[1] = 1
nums[(1 * 2) + 1 = 3] = nums[1] + nums[2] = 1 + 1 = 2
nums[(2 * 2) = 4] = nums[2] = 1
nums[(2 * 2) + 1 = 5] = nums[2] + nums[3] = 1 + 2 = 3
nums[(3 * 2) = 6] = nums[3] = 2
nums[(3 * 2) + 1 = 7] = nums[3] + nums[4] = 2 + 1 = 3
因此,nums = [0,1,1,2,1,3,2,3],最大值 3
示例 2:
输入:n = 2
输出:1
解释:根据规则,nums[0]、nums[1] 和 nums[2] 之中的最大值是 1
示例 3:
输入:n = 3
输出:2
解释:根据规则,nums[0]、nums[1]、nums[2] 和 nums[3] 之中的最大值是 2
解题思路
简单题,直接模拟生成,条件都给你了,真就周一放大假呗
代码实现
class Solution {
public int getMaximumGenerated(int n) {
int[] nums = new int[n + 1];
int max = 0;
for(int i = 0; i < nums.length; i++){
if(i <= 1) nums[i] = i;
if(2 * i >= 2 && 2 * i <= n) nums[2 * i] = nums[i];
if(2 * i + 1 >= 2 && 2 * i + 1 <= n) nums[2 * i + 1] = nums[i] + nums[i + 1];
max = Math.max(max, nums[i]);
}
return max;
}
}
一、733. 图像渲染
题目描述
有一幅以二维整数数组表示的图画,每一个整数表示该图画的像素值大小,数值在 0 到 65535 之间。
给你一个坐标 (sr, sc) 表示图像渲染开始的像素值(行 ,列)和一个新的颜色值 newColor,让你重新上色这幅图像。
为了完成上色工作,从初始坐标开始,记录初始坐标的上下左右四个方向上像素值与初始坐标相同的相连像素点,接着再记录这四个方向上符合条件的像素点与他们对应四个方向上像素值与初始坐标相同的相连像素点,……,重复该过程。将所有有记录的像素点的颜色值改为新的颜色值。
最后返回经过上色渲染后的图像。
示例 1:
输入:
image = [[1,1,1],[1,1,0],[1,0,1]]
sr = 1, sc = 1, newColor = 2
输出: [[2,2,2],[2,2,0],[2,0,1]]
解析:
在图像的正中间,(坐标(sr,sc)=(1,1)),
在路径上所有符合条件的像素点的颜色都被更改成2。
注意,右下角的像素没有更改为2,
因为它不是在上下左右四个方向上与初始点相连的像素点。
解题思路
简单的深度优先搜索算法,使用边界条件进行返回,减少判断。
代码实现
class Solution {
public int[][] floodFill(int[][] image, int sr, int sc, int newColor) {
int oldColor = image[sr][sc];
draw(image, sr, sc, newColor, oldColor);
return image;
}
void draw(int[][] image, int sr, int sc, int newColor, int oldColor){
int lineLen = image.length;
int colLen = image[].length;
if(sr < 0 || sc < 0 || sr >= lineLen || sc >= colLen || image[sr][sc] != newColor || newColor == oldColor) return;
draw(image, sr - 1, sc, newColor, oldColor);
draw(image, sr + 1, sc, newColor, oldColor);
draw(image, sr, sc - 1, newColor, oldColor);
draw(image, sr, sc + 1, newColor, oldColor);
}
}
二、695. 岛屿的最大面积
题目描述
给定一个包含了一些 0 和 1 的非空二维数组 grid 。
一个 岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在水平或者竖直方向上相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着。
找到给定的二维数组中最大的岛屿面积。(如果没有岛屿,则返回面积为 0 。)
示例 1:
[[0,0,1,0,0,0,0,1,0,0,0,0,0],
[0,0,0,0,0,0,0,1,1,1,0,0,0],
[0,1,1,0,1,0,0,0,0,0,0,0,0],
[0,1,0,0,1,1,0,0,1,0,1,0,0],
[0,1,0,0,1,1,0,0,1,1,1,0,0],
[0,0,0,0,0,0,0,0,0,0,1,0,0],
[0,0,0,0,0,0,0,1,1,1,0,0,0],
[0,0,0,0,0,0,0,1,1,0,0,0,0]]
对于上面这个给定矩阵应返回 6。注意答案不应该是 11 ,因为岛屿只能包含水平或垂直的四个方向的 1 。
示例 2:
[[0,0,0,0,0,0,0,0]]
对于上面这个给定的矩阵, 返回 0。
解题思路
使用深度优先搜索,遍历所有节点,将遍历过的节点置为0,防止死循环。
代码实现
class Solution {
public int maxAreaOfIsland(int[][] grid) {
int max = 0, cur = 0;
for(int x = 0; x < grid.length; x++){
for(int y = 0; y <grid[0].length; y++){
cur = dfs(grid, x, y);
max = Math.max(max, cur);
}
}
return max;
}
private int dfs(int[][] grid, int x, int y){
if(x < 0 || x >= grid.length || y < 0 || y >= grid[0].length || grid[x][y] == 0) return 0;
grid[x][y] = 0;
return 1 + dfs(grid, x - 1, y) + dfs(grid, x + 1, y) + dfs(grid,s x, y - 1) + dfs(grid, x, y + 1);
}
}
三、11. 盛最多水的容器
题目描述
给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
示例 1:
输入:[1,8,6,2,5,4,8,3,7]
输出:49
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
示例 2:
输入:height = [1,1]
输出:1
示例 3:
输入:height = [4,3,2,1,4]
输出:16
示例 4:
输入:height = [1,2,1]
输出:2
解题思路
使用双指针,遍历所有的可能是最大的解法,当左指针大右指针小时,右指针往左移动有可能变大,但左指针往右移动绝不可能增大
代码实现
class Solution {
public int maxArea(int[] height) {
int left = 0;
int rigth = height.length - 1;
int max = 0;
int cur = 0;
while(left != right){
cur = (right - left) * Math.min(heigth[right], height[left]);
max = Math.max(max, cur);
if(heigth[right] > height[left]) left++;
else right--;
}
return max;
}
}
四、15. 三数之和
题目描述
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
示例 2:
输入:nums = []
输出:[]
示例 3:
输入:nums = [0]
输出:[]
解题思路
使用左右指针和当前指针,遍历排序后的数组,利用排序后相同元素挨着的特性进行去重。
代码实现
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
if(nums == null || nums.length < 3) return res;
Arrays.sort(nums);
for(int i = 0; i < nums.length; i++){
if(nums[i] > 0) break;
int left = i + 1;
int right = nums.length - 1;
if(nums[i] == nums[i - 1]) continue;
while(right > left){
int sum = nums[i] + nums[left] + nums[right];
if(sum == 0){
res.add(Arrays.asList(nums[i], nums[left], nums[right]));
while(right > left && nums[left] == nums[left + 1]) left++;
while(right > left && nums[right] == nums[right - 1]) right--;
left++;
rigth--;
}
else if(sum > 0) right--;
else if(sum < 0) left++;
}
}
return res;
}
}
五、20. 有效的括号
题目描述
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
示例 1:
输入:s = "()"
输出:true
示例 2:
输入:s = "()[]{}"
输出:true
示例 3:
输入:s = "(]"
输出:false
示例 4:
输入:s = "([)]"
输出:false
示例 5:
输入:s = "{[]}"
输出:true
解题思路
使用栈实现,当碰到左括号时,往栈中放入对应的右括号,当碰到右括号时出栈,检查是否匹配,如果匹配就弹出,直到栈中为空
代码实现
class Solution {
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
char[] cs = s.toCharArray();
for(int i = 0; i < cs.length; i++){
if(cs[i] == '(') stack.push(')');
else if(cs[i] == '{') stack.push('}');
else if(cs[i] == '[') stack.push(']');
else if(stack.isEmpty() || stack.peek() != cs[i]) return false;
else stack.pop;
}
return stack.isEmpty();
}
}

浙公网安备 33010602011771号