排列硬币
讨论 1
二分查找
class Solution {
public int arrangeCoins(int n) {
int left = 1, right = n;
while (left < right) {
int mid = (right - left + 1) / 2 + left;
if ((long) mid * (mid + 1) <= (long) 2 * n) {
left = mid;
} else {
right = mid - 1;
}
}
return left;
}
}
讨论 2
数学
class Solution {
public int arrangeCoins(int n) {
return (int) ((Math.sqrt((long) 8 * n + 1) - 1) / 2);
}
}
第K个缺失的正整数
讨论 1
枚举
我们可以顺序枚举。
用一个变量 current
表示当前应该出现的数,从 1
开始,每次循环都让该变量递增。用一个指针ptr
指向数组中没有匹配的第一个元素,每轮循环中将该元素和 current
进行比较,如果相等,则指针后移,否则指针留在原地不动,说明缺失正整数current
。我们用 missCount
变量记录缺失的正整数的个数,每次发现有正整数缺失的时候,该变量自增,并且记录这个缺失的正整数,直到我们找到第 k
个缺失的正整数。
class Solution {
public int findKthPositive(int[] arr, int k) {
int missCount = 0, lastMiss = -1, current = 1, ptr = 0;
for (missCount = 0; missCount < k; ++current) {
if (current == arr[ptr]) {
ptr = (ptr + 1 < arr.length) ? ptr + 1 : ptr;
} else {
++missCount;
lastMiss = current;
}
}
return lastMiss;
}
}
讨论 2
class Solution {
public int findKthPositive(int[] arr, int k) {
if (arr[0] > k) {
return k;
}
int l = 0, r = arr.length;
while (l < r) {
int mid = (l + r) >> 1;
int x = mid < arr.length ? arr[mid] : Integer.MAX_VALUE;
if (x - mid - 1 >= k) {
r = mid;
} else {
l = mid + 1;
}
}
return k - (arr[l - 1] - (l - 1) - 1) + arr[l - 1];
}
}