トピック
ソートされた整数配列 arr、2 つの整数 k および x を指定すると、配列内の x に最も近い k 個の整数が返されます。結果も昇順に並べ替える必要があります。
次の場合、整数 a は整数 b よりも x に近くなります。
- |a - x| < |b - x|、または
- |a - x| == |b - x| そして a < b
例 1:
入力: arr = [1,2,3,4,5]、k = 4、x = 3
出力: [1,2,3,4]
例 2:
入力: arr = [1,2,3,4,5]、k = 4、x = -1
出力: [1,2,3,4]
制約:
- 1 <= k <= arr.length
- 1 <= arr.length <= 104
- arr は昇順にソートされます。
- -10^4 <= arr[i]、x <= 10^4
コード
class Solution {
public:
int findX(vector<int>& arr, int x) {
int low = 0, high = arr.size() - 1;
while(low < high)
{
int mid = (low + high) / 2;
if(arr[mid] == x)
return mid;
if(arr[mid] < x)
low = mid + 1;
else
high = mid;
}
if(arr[high] > x)
{
if(high > 0 && x - arr[high-1] < arr[high] - x)
return high - 1;
}
return high;
}
vector<int> findClosestElements(vector<int>& arr, int k, int x) {
vector<int> res;
if(arr.size() < 1)
return res;
if(x <= arr[0])
{
res = vector(arr.begin(), arr.begin()+k);
return res;
}
if(x >= arr[arr.size() - 1])
{
res = vector(arr.end()-k, arr.end());
return res;
}
int idx = findX(arr, x), startIdx = idx, endIdx = idx;
for(int j = 1; j < k && startIdx >= 0 && endIdx < arr.size(); j++)
{
if(startIdx == 0)
{
endIdx++;
}
else if(endIdx == arr.size() - 1)
{
startIdx--;
}
else
{
if(x - arr[startIdx - 1] <= arr[endIdx + 1] - x)
{
startIdx--;
}
else
{
endIdx++;
}
}
}
//cout << idx << " " << startIdx << " " << endIdx << endl;
res = vector(arr.begin()+startIdx, arr.begin()+endIdx+1);
return res;
}
};