1.找到小镇的法官 leetcode 997
在一个小镇里,按从 1 到 N 标记了 N 个人。传言称,这些人中有一个是小镇上的秘密法官。
如果小镇的法官真的存在,那么:
小镇的法官不相信任何人。
每个人(除了小镇法官外)都信任小镇的法官。
只有一个人同时满足属性 1 和属性 2 。
给定数组 trust,该数组由信任对 trust[i] = [a, b] 组成,表示标记为 a 的人信任标记为 b 的人。
如果小镇存在秘密法官并且可以确定他的身份,请返回该法官的标记。否则,返回 -1。
示例 1:输入:N = 2, trust = [[1,2]] 输出:2
示例 2:输入:N = 3, trust = [[1,3],[2,3]] 输出:3
示例 3:输入:N = 3, trust = [[1,3],[2,3],[3,1]] 输出:-1
示例 4:输入:N = 3, trust = [[1,2],[2,3]] 输出:-1
示例 5:输入:N = 4, trust = [[1,3],[1,4],[2,3],[2,4],[4,3]] 输出:3
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-the-town-judge
public int findJudge(int N, int[][] trust) {
//小镇人数为N,N为1时此人就是法官
if(N == 1){
return 1;
}
int[] cur = new int[N+1]; //数组默认从0开始,0不算
//index数组下标0代表投票者,下标1代表被投票者
for(int[] index:trust){
cur[index[0]]--; //投票者投票后票数减1
cur[index[1]]++; //候选人得票后票数加1
}
int judge = -1; //代表法官
//循环结束后,代表大家都投票了,此时法官手中一定为N-1票
for(int i = 1; i <=N; i++){
if(cur[i] == N-1){
judge = i; //法官就是第i个人
return judge; //break也可以
}
}
//循环出来表示没找到
return judge;
}
2.将数组分成和相等的三个部分 leetcode 1013
给你一个整数数组 A,只有可以将其划分为三个和相等的非空部分时才返回 true,否则返回 false。
形式上,如果可以找出索引 i+1 < j 且满足 A[0] + A[1] + … + A[i] == A[i+1] + A[i+2] + … + A[j-1] == A[j] + A[j-1] + … + A[A.length - 1] 就可以将数组三等分。
示例 1:
输入:[0,2,1,-6,6,-7,9,1,2,0,1] 输出:true 解释:0 + 2 + 1 = -6 + 6 - 7 + 9 + 1= 2 + 0 + 1
示例 2:输入:[0,2,1,-6,6,7,9,-1,2,0,1] 输出:false
示例 3:输入:[3,3,6,5,-2,2,5,1,-9,4] 输出:true 解释:3 + 3 = 6 = 5 - 2 + 2 + 5 + 1 - 9 + 4
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/partition-array-into-three-parts-with-equal-sum
public boolean canThreePartsEqualSum(int[] arr) {
int sum = 0;
for (int num: arr) {
sum += num;
}
// 数组A的和如果不能被3整除返回false
if (sum % 3 != 0) {
return false;
}
// 遍历数组累加,每累加到目标值cnt加1,表示又找到1段,
// 找到2段后就返回true(i只能到数组A的倒数第二个元素,保证了有第3段)
sum /= 3;
int curSum = 0, cnt = 0;
for (int i = 0; i < arr.length - 1; i++) {
curSum += arr[i];
if (curSum == sum) {
cnt++;
if (cnt == 2) {
return true;
}
curSum = 0;
}
}
return false;
}
3.二维网格的迁移 leetcode 1260
给你一个 m 行 n 列的二维网格 grid 和一个整数 k。你需要将 grid 迁移 k 次。
每次「迁移」操作将会引发下述活动:
位于 grid[i][j] 的元素将会移动到 grid[i][j + 1]。
位于 grid[i][n - 1] 的元素将会移动到 grid[i + 1][0]。
位于 grid[m - 1][n - 1] 的元素将会移动到 grid[0][0]。
请你返回 k 次迁移操作后最终得到的 二维网格。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shift-2d-grid
public List<List<Integer>> shiftGrid(int[][] grid, int k) {
// 外部循环控制移动k次
for (;k > 0; k--) {
//新建一个二维数组
int[][] newGrid = new int[grid.length][grid[0].length];
// 移动的第一步:把前m-1列元素平行向后移动
for (int row = 0; row < grid.length; row++) {
for (int col = 0; col < grid[0].length - 1; col++) {
newGrid[row][col + 1] = grid[row][col];
}
}
// 移动的第二步:把原来最后一列除了最后一行元素以外的元素移动
for (int row = 0; row < grid.length - 1; row++) {
newGrid[row + 1][0] = grid[row][grid[0].length - 1];
}
// 把右下角的元素移动到左上角
newGrid[0][0] = grid[grid.length - 1][grid[0].length - 1];
grid = newGrid;
}
List<List<Integer>> result = new ArrayList<>();
for (int[] row : grid) {
List<Integer> listRow = new ArrayList<>();
for (int v : row) {
listRow.add(v);
}
result.add(listRow);
}
return result;
}