一、leetcode题目( 今天的leetcode是写的周赛题目)
昨天状态不好,摸鱼一天。
1.数组中最长的方波
题目描述
给你一个整数数组 nums
。如果 nums
的子序列满足下述条件,则认为该子序列是一个 方波 :
子序列的长度至少为 2
,并且
将子序列从小到大排序 之后 ,除第一个元素外,每个元素都是前一个元素的 平方 。
返回 nums
中 最长方波 的长度,如果不存在 方波 则返回 -1
。
子序列 也是一个数组,可以由另一个数组删除一些或不删除元素且不改变剩余元素的顺序得到。
测试用例
输入:
nums = [4,3,6,16,8,2]
输出:
3
解释:
选出子序列 [4,16,2] 。排序后,得到 [2,4,16] 。
4 = 2 * 2.
16 = 4 * 4.
因此,[4,16,2] 是一个方波.
可以证明长度为 4 的子序列都不是方波。
如果nums的子序列都不是方波,则返回-1
思路
先排序,然后直接找其平方数即可。再使用HashSet查找,数组中是否存在,可节省再nums
中查找的复杂度
算法实现
public int longestSquareStreak(int[] nums) {
int n = nums.length;
Arrays.sort(nums);
HashSet<Integer> set = new HashSet<>();
for(int num : nums){
if(!set.contains(num)) set.add(num);
}
int ans = 0;
for(int i = 0; i < n; i++){
int cur = nums[i];
int max = 0;
while(set.contains(cur)){
max++;
cur *= cur;
}
ans = Math.max(ans, max);
}
return ans == 1 ? -1 : ans;
}
2.矩阵查询可获得的最大分数
给你一个大小为 m x n
的整数矩阵 grid
和一个大小为 k
的数组 queries
。
找出一个大小为 k 的数组 answer
,且满足对于每个整数 queres[i]
,你从矩阵 左上角 单元格开始,重复以下过程:
如果 queries[i] 严格 大于你当前所处位置单元格,如果该单元格是第一次访问,则获得 1
分,并且你可以移动到所有 4
个方向(上、下、左、右)上任一 相邻 单元格。
否则,你不能获得任何分,并且结束这一过程。
在过程结束后,answer[i]
是你可以获得的最大分数。注意,对于每个查询,你可以访问同一个单元格 多次 。
返回结果数组 answer
。
测试用例
输入:
grid = [[1,2,3],[2,5,7],[3,5,1]], queries = [5,6,2]
输出:
[5,8,1]
解释:
上图展示了每个查询中访问并获得分数的单元格。
思路
另外建立一个辅助数组,避免一个数字遍历多次, b f s bfs bfs, d f s dfs dfs都可
dfs算法实现
class Solution {
public int[] maxPoints(int[][] grid, int[] queries) {
boolean[][] matrix = new boolean[grid.length][grid[0].length];
int[] ans = new int[queries.length];
int i = 0;
for(int querie : queries){
ans[i++] = dfs(grid, matrix, 0, 0, querie);
for(boolean[] arr : matrix){
Arrays.fill(arr, false);
}
}
return ans;
}
private int dfs(int[][] grid, boolean[][] matrix, int i, int j, int max){
if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || matrix[i][j] == true || grid[i][j] >= max) return 0;
matrix[i][j] = true;
return 1+dfs(grid,matrix,i+1,j,max)+dfs(grid,matrix,i-1,j,max)+dfs(grid,matrix,i,j+1,max)+dfs(grid,matrix,i,j-1,max);
}
}
第17个测试用例超时,也在情理之中,queries
数组中每次数字都需要从头开始计算,dfs在这种情况下属于暴力算法。超时之后想到的第二种方式就是记忆化搜索,不过尝试后,直接错了。就不贴上来了。这个问题明天再看看题解,再细细思考吧。(先到这里留一个坑)
二、蓝桥题目
1.
题目描述
输入描述
给定一棵包含
N
N
N 个节点的完全二叉树,树上每个节点都有一个权值,按从 上到下、从左到右的顺序依次是
A
1
,
A
2
,
⋅
⋅
⋅
A
N
A_1, A_2, ··· A_N
A1,A2,⋅⋅⋅AN
,如下图所示:
现在小明要把相同深度的节点的权值加在一起,他想知道哪个深度的节点 权值之和最大?如果有多个深度的权值和同为最大,请你输出其中最小的深度。
注:根的深度是 1
输入描述
第一行包含一个整数
N
(
1
≤
N
≤
1
0
5
)
N
(
1
≤
N
≤
1
0
5
)
N(1 \leq N \leq 10^5)N(1≤N≤10^5)
N(1≤N≤105)N(1≤N≤105)。
第二行包含
N
N
N 个整数
A
1
,
A
2
,
⋅
⋅
⋅
A
N
(
−
1
0
5
≤
A
i
≤
1
0
5
)
A_1, A_2, ··· A_N (−10^5 \leq A_i \leq 10^5)
A1,A2,⋅⋅⋅AN(−105≤Ai≤105)
输出描述
输出一个整数代表答案。
2.测试用例
输入:
7
1 6 5 4 3 2 1
输出:
2
3.思路
我的第一思路就是bfs,测试用例没全过,明天再看看(再到这里留一个坑)
4.算法实现
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
//在此输入您的代码...
int n = scan.nextInt();
int[] tree = new int[n+1];
for(int i = 1; i <= n; i++){
tree[i] = scan.nextInt();
}
int path = (n + 1) / 2;
int ans = 0;
int max = Integer.MIN_VALUE;
int k = 1;
while(k < path){
int cur = 0;
for(int i = 2*k; i < (k+1)*2; i++){
cur += tree[i];
}
if(cur > max){
max = cur;
ans = k;
}
k++;
}
System.out.println(ans);
scan.close();
}
}