779.第K个语法符号
在第一行我们写上一个 0。接下来的每一行,将前一行中的0替换为01,1替换为10。
给定行数 N 和序数 K,返回第 N 行中第 K个字符。(K从1开始)
例子:
输入: N = 1, K = 1
输出: 0
输入: N = 2, K = 1
输出: 0
输入: N = 2, K = 2
输出: 1
输入: N = 4, K = 5
输出: 1
解释:
第一行: 0
第二行: 01
第三行: 0110
第四行: 01101001
注意:
N 的范围 [1, 30].
K 的范围 [1, 2^(N-1)].
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/k-th-symbol-in-grammar
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
方法一:按列找规律
- 第1列的数字为0。
- 当列数是偶数列时,该列的数值和K/2列的数值相反。
- 当列数是奇数列时,该列的数值和(K+1)/2列的数值相同。
int kthGrammar(int N, int K){
if (K==1) {
return 0;
}
if (K % 2 == 0) {
return !kthGrammar(N , K/2);
}
else {
return kthGrammar(N , (K+1)/2);
}
}
方法二:按行找规律
- 第一行的长度为2^0 ,第二行的长度为2^1,……则第 N 行的长度为 2^(N-1)。
- 若 K <= N 行长度的一半 时,K等于 N - 1 行的第 K 个数。
- 若 K>N 行长度的一半时,K等于 N - 1 行的第( K - 行长度一半) 个数取反。
int kthGrammar(int N, int K){
int i;
if (N == 1) {
return 0;
}
if (N == 2) {
if (K == 1) {
return 0;
}
else {
return 1;
}
}
int L = 1;
for (i = 1 ; i < N ; i++) {
L *= 2;
}
if (K <= (L/2)) {
return kthGrammar(N - 1 , K);
}
else {
return !kthGrammar(N - 1 , K-(L/2));
}
}
第一种方法更简单些,但实际情况更会考虑到方法二。
283.移动零
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:
1.必须在原数组上操作,不能拷贝额外的数组。
2.尽量减少操作次数。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/move-zeroes
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
方法一:遇到非零就放前面,后面补零
void moveZeroes(int* nums, int numsSize){
int i, j = 0;
for (i = 0; i < numsSize; i++) {
if (nums[i] != 0) {
nums[j++] = nums[i];
}
}
for (j; j < numsSize; j++) {
nums[j] = 0;
}
}
方法二:将数组中所有零放在一起,去掉,补在后面
void moveZeroes(int* nums, int numsSize){
int i, t = 0;
for (i = 0; i < numsSize; i++) {
if (nums[i] == 0){
t++;
}
else if (t > 0) {
nums[i - t] = nums[i];
nums[i] = 0;
}
}
}