36 有效的数独
36. 有效的数独 - 力扣(LeetCode) (leetcode-cn.com)
请你判断一个 9x9
的数独是否有效。只需要 根据以下规则 ,验证已经填入的数字是否有效即可。
- 数字
1-9
在每一行只能出现一次。 - 数字
1-9
在每一列只能出现一次。 - 数字
1-9
在每一个以粗实线分隔的3x3
宫内只能出现一次。(请参考示例图)
数独部分空格内已填入了数字,空白格用 '.'
表示。
注意:
- 一个有效的数独(部分已被填充)不一定是可解的。
- 只需要根据以上规则,验证已经填入的数字是否有效即可。
示例 1:
输入:board =
[["5","3",".",".","7",".",".",".","."]
,["6",".",".","1","9","5",".",".","."]
,[".","9","8",".",".",".",".","6","."]
,["8",".",".",".","6",".",".",".","3"]
,["4",".",".","8",".","3",".",".","1"]
,["7",".",".",".","2",".",".",".","6"]
,[".","6",".",".",".",".","2","8","."]
,[".",".",".","4","1","9",".",".","5"]
,[".",".",".",".","8",".",".","7","9"]]
输出:true
示例 2:
输入:board =
[["8","3",".",".","7",".",".",".","."]
,["6",".",".","1","9","5",".",".","."]
,[".","9","8",".",".",".",".","6","."]
,["8",".",".",".","6",".",".",".","3"]
,["4",".",".","8",".","3",".",".","1"]
,["7",".",".",".","2",".",".",".","6"]
,[".","6",".",".",".",".","2","8","."]
,[".",".",".","4","1","9",".",".","5"]
,[".",".",".",".","8",".",".","7","9"]]
输出:false
解释:除了第一行的第一个数字从 5 改为 8 以外,空格内其他数字均与 示例1 相同。
但由于位于左上角的 3x3 宫内有两个 8 存在, 因此这个数独是无效的。
这个题是看 是否有效 ,不需要解出答案
public boolean isValidSudoku(char[][] board) {
boolean[][] rows = new boolean[9][10];//行是否有效
boolean[][] colums = new boolean[9][10];//列.
boolean[][] bucket = new boolean[9][10];//格.
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
int p = 3 * (i / 3) + (j / 3);//算出是第几个九宫格
if (board[i][j] != '.') {
int num = board[i][j] - '0';
if (rows[i][num] || colums[j][num] || bucket[p][num]) {
return false;
}
rows[i][num] = true;
colums[j][num] = true;
bucket[p][num] = true;
}
}
}
return true;
}
38 外观数列
38. 外观数列 - 力扣(LeetCode) (leetcode-cn.com)
给定一个正整数 n ,输出外观数列的第 n 项。
「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。
你可以将其视作是由递归公式定义的数字字符串序列:
countAndSay(1) = “1”
countAndSay(n) 是对 countAndSay(n-1) 的描述,然后转换成另一个数字字符串。
前五项如下:
-
1
-
11
-
21
-
1211
-
111221 第一项是数字 1 描述前一项,这个数是 1 即 “ 一 个 1 ”,记作 "11" 描述前一项,这个数是 11 即 “ 二 个 1 ” ,记作 "21" 描述前一项,这个数是 21 即 “ 一 个 2 + 一 个 1 ” ,记作 "1211" 描述前一项,这个数是 1211 即 “ 一 个 1 + 一 个 2 + 二 个 1 ” ,记作 "111221" 要 描述 一个数字字符串,首先要将字符串分割为 最小 数量的组,每个组都由连续的最多 相同字符 组成。然后对于每个组,先描述字符的数量,然后描述字符,形成一个描述组。要将描述转换为数字字符串,先将每组中的字符数量用数字替换,再将所有描述组连接起来。
例如,数字字符串 “3322251” 的描述如下图:
示例 1:
输入:n = 1
输出:“1”
解释:这是一个基本样例。
示例 2:
输入:n = 4
输出:“1211”
解释:
countAndSay(1) = “1”
countAndSay(2) = 读 “1” = 一 个 1 = “11”
countAndSay(3) = 读 “11” = 二 个 1 = “21”
countAndSay(4) = 读 “21” = 一 个 2 + 一 个 1 = “12” + “11” = “1211”
读第N个数的时候 ,先把N-1 的知道 - 递归
public String countAndSay(int n) {
if (n < 1) {
return "";
}
if (n == 1) {
return "1";
}
char[] c = countAndSay(n - 1).toCharArray();
StringBuilder sb = new StringBuilder();
int time = 1;
for (int i = 1; i < c.length; i++) {
if (c[i - 1] == c[i]) {
time++;
} else {
sb.append(String.valueOf(time));
sb.append(String.valueOf(c[i - 1]));
time = 1;
}
}
sb.append(String.valueOf(time));
sb.append(String.valueOf(c[c.length-1]));
return sb.toString();
}
41 缺失的第一个正数
41. 缺失的第一个正数 - 力扣(LeetCode) (leetcode-cn.com)
给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。
请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。
示例 1:
输入:nums = [1,2,0]
输出:3
示例 2:
输入:nums = [3,4,-1,1]
输出:2
示例 3:
输入:nums = [7,8,9,11,12]
输出:1
要求是 时间:O(N) 空间 O(1)
在数组中 i 位置存放 i+1值 负数 和大于 arr.length 的数属于捣乱项
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public int firstMissingPositive(int[] nums) {
for (int i = 0; i < nums.length; i++){
//nums[i]在1到 nums.length之间,就进行归位
// nums[nums[i] - 1] != nums[i] 当前位置的值 例如 i = 3 存的值应该是4
while (nums[i] > 0 && nums[i] <= nums.length && nums[nums[i] - 1] != nums[i]){
swap(nums, i, nums[i] - 1);
}
}
//遍历找到 缺失的
for (int i = 0; i < nums.length; i++){
if (nums[i] != i + 1) {
return i + 1;
}
}
return nums.length + 1;
}
42 接雨水
42. 接雨水 - 力扣(LeetCode) (leetcode-cn.com)
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
示例 1:
输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。
示例 2:
输入:height = [4,2,0,3,2,5]
输出:9
i位置的水量 = i位置左侧 和右侧的最大值
辅助数组 : 左侧最大值 右侧最大值
二:双指针 0位置 和N 位置 不能保存水量,可以先把左侧最大值设置为0位置的值,右侧 N位置的值
那一侧小 结算那一侧
public int trap(int[] height) {
if (height.length < 2) {
return 0;
}
int L = 1;
int R = height.length - 2;
int leftMax = height[0];//左侧最大值
int rightMax = height[height.length - 1];//右侧最大值
int ans = 0;
while (L <= R) {
if (leftMax < rightMax) {//左侧 < 右侧 ,结算左侧 看看要不要更新左侧最大值,L++
ans += Math.max(leftMax - height[L], 0);
leftMax = Math.max(leftMax, height[L++]);
} else {//结算右侧 R--
ans += Math.max(rightMax - height[R], 0);
rightMax = Math.max(rightMax, height[R--]);
}
}
return ans;
}