一、LeetCode 378 有序矩阵中第K小的元素
题目描述:
给你一个 n x n 矩阵 matrix ,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素。
请注意,它是 排序后 的第 k 小元素,而不是第 k 个 不同 的元素。
思路:
二分查询
代码如下:
class Solution {
public:
int kthSmallest(vector<vector<int>>& matrix, int k) {
int m=matrix.size();
int n=matrix[0].size();
if(k==0) return matrix[0][0];
if(k==m*n) return matrix[m-1][n-1];
int left=matrix[0][0],right=matrix[m-1][n-1],mid=0;
while(left<right){
mid=left+(right-left)/2;
if(find(matrix,mid)<k){
left=mid+1;
}
else{
right=mid;
}
}
return left;
}
int find(vector<vector<int>>matrix,int mid){
int res=0;
int i=0,j=matrix[0].size()-1;
while(i<matrix.size()&&j>=0){
if(matrix[i][j]<=mid){
res+=j+1;
i++;
}
else{
j--;
}
}
return res;
}
};
二、LeetCode 719 找出第k小的距离对
题目描述:
给定一个整数数组,返回所有数对之间的第 k 个最小距离。一对 (A, B) 的距离被定义为 A 和 B 之间的绝对差值。
示例 1:
输入:
nums = [1,3,1]
k = 1
输出:0
解释:
所有数对如下:
(1,3) -> 2
(1,1) -> 0
(3,1) -> 2
因此第 1 个最小距离的数对是 (1,1),它们之间的距离为 0。
思路:
二分法O(nlogn)
代码如下:
class Solution {
public:
int smallestDistancePair(vector<int>& nums, int k) {
sort(nums.begin(),nums.end());
int left=0,right=nums.back()-nums[0];
while(left<right){
int i=0;
int cnt=0;
int mid=left+(right-left)/2;
for(int j=0;j<nums.size();j++){
while(nums[j]-nums[i]>mid) i++;
cnt+=j-i;
}
if(cnt<k) left=mid+1;
else right=mid;
}
return left;
}
};
三、LeetCode 1352 最后K个数的乘积
题目描述:
请你实现一个「数字乘积类」ProductOfNumbers,要求支持下述两种方法:
- add(int num)
将数字 num 添加到当前数字列表的最后面。
2. getProduct(int k)
返回当前数字列表中,最后 k 个数字的乘积。
你可以假设当前列表中始终 至少 包含 k 个数字。
题目数据保证:任何时候,任一连续数字序列的乘积都在 32-bit 整数范围内,不会溢出。
思路:
方法一:当然暴力是一种方法
方法二:前缀积;但是考虑到存在0这个数,所以当遇到num=0时,就从新开始前缀积的运算,同时还要记录下是0的位置,可以快速判断结果
代码如下:
class ProductOfNumbers {
public:
vector<int>prod;
int zeroInx;
ProductOfNumbers() {
zeroInx=-1;
}
void add(int num) {
//如果num为0,将其加到prod中,并记录其索位置
if(num==0){
prod.push_back(num);
zeroInx=prod.size()-1;
}
//如果prod中没有数,或者前一个数刚好是0,那么直接加到prod中
else if(prod.size()==0||zeroInx==prod.size()-1){
prod.push_back(num);
}
//否则记录其累乘结果
else{
prod.push_back(num*prod[prod.size()-1]);
}
}
int getProduct(int k) {
int n=prod.size();
if(n-k<=zeroInx){
return 0;
}
if(n-k-1==zeroInx){
return prod[n-1];
}
return prod[n-1]/prod[n-k-1];
}
};
/**
* Your ProductOfNumbers object will be instantiated and called as such:
* ProductOfNumbers* obj = new ProductOfNumbers();
* obj->add(num);
* int param_2 = obj->getProduct(k);
*/