5364. 按既定顺序创建目标数组
给你两个整数数组 nums 和 index。你需要按照以下规则创建目标数组:
目标数组 target 最初为空。
按从左到右的顺序依次读取 nums[i] 和 index[i],在 target 数组中的下标 index[i] 处插入值 nums[i] 。
重复上一步,直到在 nums 和 index 中都没有要读取的元素。
请你返回目标数组。
题目保证数字插入位置总是存在。
示例 1:
输入:nums = [0,1,2,3,4], index = [0,1,2,2,1]
输出:[0,4,1,3,2]
解释:
nums index target
0 0 [0]
1 1 [0,1]
2 2 [0,1,2]
3 2 [0,1,3,2]
4 1 [0,4,1,3,2]
示例 2:
输入:nums = [1,2,3,4,0], index = [0,1,2,3,0]
输出:[0,1,2,3,4]
解释:
nums index target
1 0 [1]
2 1 [1,2]
3 2 [1,2,3]
4 3 [1,2,3,4]
0 0 [0,1,2,3,4]
示例 3:
输入:nums = [1], index = [0]
输出:[1]
提示:
1 <= nums.length, index.length <= 100
nums.length == index.length
0 <= nums[i] <= 100
0 <= index[i] <= i
思路
用
LinkedList
的
add(int index, Element E)
方法实现该逻辑
代码
class Solution {
public int[] createTargetArray(int[] nums, int[] index) {
LinkedList<Integer> list = new LinkedList<>();
int i = 0, n = nums.length;
for (i=0; i<n; ++i) {
list.add(index[i], nums[i]);
}
int[] ans = new int[n];
for (i=0; i<n; ++i) {
ans[i] = list.get(i);
}
return ans;
}
}
5178. 四因数
给你一个整数数组 nums,请你返回该数组中恰有四个因数的这些整数的各因数之和。
如果数组中不存在满足题意的整数,则返回 0 。
示例:
输入:nums = [21,4,7]
输出:32
解释:
21 有 4 个因数:1, 3, 7, 21
4 有 3 个因数:1, 2, 4
7 有 2 个因数:1, 7
答案仅为 21 的所有因数的和。
提示:
1 <= nums.length <= 10^4
1 <= nums[i] <= 10^5
代码
class Solution {
public int sumFourDivisors(int[] nums) {
int ans = 0, i = 0, cnt = 0, mid = 0, mod = 0;
for (int num: nums) {
mid = (int) Math.sqrt(num);
if (mid * mid == num) {
continue;
}
cnt = 0;
for (i=2; i<=mid; ++i) {
if (num % i == 0) {
if (cnt == 0) {
mod = i;
++cnt;
} else {
++cnt;
break;
}
}
}
if (cnt == 0 || cnt == 2) {
continue;
}
ans += 1 + num + mod + num / mod;
}
return ans;
}
}
5366. 检查网格中是否存在有效路径
给你一个 m x n 的网格 grid。网格里的每个单元都代表一条街道。grid[i][j] 的街道可以是:
1 表示连接左单元格和右单元格的街道。
2 表示连接上单元格和下单元格的街道。
3 表示连接左单元格和下单元格的街道。
4 表示连接右单元格和下单元格的街道。
5 表示连接左单元格和上单元格的街道。
6 表示连接右单元格和上单元格的街道。
你最开始从左上角的单元格 (0,0) 开始出发,网格中的「有效路径」是指从左上方的单元格 (0,0) 开始、一直到右下方的 (m-1,n-1) 结束的路径。该路径必须只沿着街道走。
注意:你 不能 变更街道。
如果网格中存在有效的路径,则返回 true,否则返回 false 。
示例 1:
输入:grid = [[2,4,3],[6,5,2]]
输出:true
解释:如图所示,你可以从 (0, 0) 开始,访问网格中的所有单元格并到达 (m - 1, n - 1) 。
示例2:
输入:grid = [[1,2,1],[1,2,1]]
输出:false
解释:如图所示,单元格 (0, 0) 上的街道没有与任何其他单元格上的街道相连,你只会停在 (0, 0) 处。
示例 3:
输入:grid = [[1,1,2]]
输出:false
解释:你会停在 (0, 1),而且无法到达 (0, 2) 。
示例 4:
输入:grid = [[1,1,1,1,1,1,3]]
输出:true
示例 5:
输入:grid = [[2],[2],[2],[2],[2],[2],[6]]
输出:true
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 300
1 <= grid[i][j] <= 6
思路
最基本的dfs. 定义一系列常量代表街道的方向和匹配来避免
switch ... case ...
代码
class Solution {
private static final int[][] X = {{0, 0}, {1, -1}, {1, 0}, {0, 1}, {-1, 0}, {0, -1}}, Y = {{-1, 1}, {0, 0}, {0, -1}, {1, 0}, {0, -1}, {1, 0}};
private static final int[][][] MATCH = {{{0, 3, 5}, {0, 2, 4}}, {{1, 4, 5}, {1, 2, 3}}, {{1, 4, 5}, {0, 3, 5}}, {{0, 2, 4}, {1, 4, 5}}, {{1, 2, 3}, {0, 3, 5}}, {{0, 2, 4}, {1, 2, 3}}};
private boolean dfs(int x, int y, int m, int n, int[][] grid, boolean[][] vis) {
if (x == m-1 && y == n-1) {
return true;
}
vis[x][y] = true;
int i = 0, j = 0, nx = 0, ny = 0, dir = grid[x][y] - 1, ndir = 0;
for (i=0; i<=1; ++i) {
nx = x + X[dir][i];
ny = y + Y[dir][i];
if (nx < 0 || ny < 0 || nx >= m || ny >= n || vis[nx][ny]) {
continue;
}
ndir = grid[nx][ny] - 1;
for (j=0; j<=2; ++j) {
if (ndir == MATCH[dir][i][j]) {
break;
}
}
if (j == 3) {
continue;
}
if (dfs(nx, ny, m, n, grid, vis)) {
return true;
}
}
return false;
}
public boolean hasValidPath(int[][] grid) {
int m = grid.length, n = grid[0].length;
boolean[][] vis = new boolean[m][n];
return dfs(0, 0, m, n, grid, vis);
}
}
5367. 最长快乐前缀
「快乐前缀」是在原字符串中既是 非空 前缀也是后缀(不包括原字符串自身)的字符串。
给你一个字符串 s,请你返回它的 最长快乐前缀。
如果不存在满足题意的前缀,则返回一个空字符串。
示例 1:
输入:s = “level”
输出:“l”
解释:不包括 s 自己,一共有 4 个前缀(“l”, “le”, “lev”, “leve”)和 4 个后缀(“l”, “el”, “vel”, “evel”)。最长的既是前缀也是后缀的字符串是 “l” 。
示例 2:
输入:s = “ababab”
输出:“abab”
解释:“abab” 是最长的既是前缀也是后缀的字符串。题目允许前后缀在原字符串中重叠。
示例 3:
输入:s = “leetcodeleet”
输出:“leet”
示例 4:
输入:s = “a”
输出:""
提示:
1 <= s.length <= 10^5
s 只含有小写英文字母
思路
就是kmp算法求next数组部分,时间复杂度O(n)
代码
class Solution {
public String longestPrefix(String s) {
int n = s.length(), i = 0, j = 0;
int[] next = new int[n];
for(j = 1 ; j < n ; ++j) {
while(s.charAt(i) != s.charAt(j) && i > 0) {
i = next[i-1];
}
if(s.charAt(i) == s.charAt(j)) {
++i;
next[j] = i;
}
else {
next[j] = 0;
}
}
return s.substring(0, i);
}
}