🧠
Brute Force (Sliding Window Check)
💡 Starting with brute force helps understand the problem deeply by checking all possible windows of size k and comparing their closeness to x. Though inefficient, it builds intuition about what 'closest' means and how to compare windows.
Intuition
Check every contiguous subarray of length k and find which one has the smallest distance to x by comparing the edges using the problem's tie-breaker rule. Return the first such subarray.
Algorithm
- Initialize a variable to track the minimum distance and the starting index of the best window.
- Iterate over all windows of size k in the array.
- For each window, compare the distances of the left and right edges to x using the problem's tie-breaker rule.
- Update the best window if the current window is closer to x.
- Return the subarray starting at the best window index.
💡 This approach is straightforward but requires checking many windows, which is inefficient for large arrays.
from typing import List
def findClosestElements(arr: List[int], k: int, x: int) -> List[int]:
n = len(arr)
best_start = 0
for start in range(n - k + 1):
left = arr[start]
right = arr[start + k - 1]
# Compare distances with tie-breaker
if start == 0:
best_start = 0
continue
prev_left = arr[best_start]
prev_right = arr[best_start + k - 1]
# Compare current window edges with best window edges
# If current window is closer, update best_start
# Use problem's tie-breaker: compare left edges first, then right edges
def is_closer(l1, r1, l2, r2, x):
dist1_left = abs(l1 - x)
dist2_left = abs(l2 - x)
if dist1_left < dist2_left:
return True
elif dist1_left > dist2_left:
return False
else:
if l1 < l2:
return True
elif l1 > l2:
return False
else:
dist1_right = abs(r1 - x)
dist2_right = abs(r2 - x)
if dist1_right < dist2_right:
return True
elif dist1_right > dist2_right:
return False
else:
return r1 < r2
if is_closer(left, right, prev_left, prev_right, x):
best_start = start
return arr[best_start:best_start + k]
# Driver code
if __name__ == '__main__':
print(findClosestElements([1,2,3,4,5], 4, 3)) # Output: [1,2,3,4]
Line Notes
n = len(arr)Calculate array length to know how many windows to check
for start in range(n - k + 1)Iterate over all possible windows of size k
# Compare distances with tie-breakerUse problem's tie-breaker rule to compare closeness of windows
if is_closer(left, right, prev_left, prev_right, x)Update best window if current window is closer
import java.util.*;
public class Solution {
public static List<Integer> findClosestElements(int[] arr, int k, int x) {
int n = arr.length;
int bestStart = 0;
for (int start = 0; start <= n - k; start++) {
int left = arr[start];
int right = arr[start + k - 1];
if (start == 0) {
bestStart = 0;
continue;
}
int prevLeft = arr[bestStart];
int prevRight = arr[bestStart + k - 1];
if (isCloser(left, right, prevLeft, prevRight, x)) {
bestStart = start;
}
}
List<Integer> result = new ArrayList<>();
for (int i = bestStart; i < bestStart + k; i++) {
result.add(arr[i]);
}
return result;
}
private static boolean isCloser(int l1, int r1, int l2, int r2, int x) {
int dist1Left = Math.abs(l1 - x);
int dist2Left = Math.abs(l2 - x);
if (dist1Left < dist2Left) return true;
else if (dist1Left > dist2Left) return false;
else {
if (l1 < l2) return true;
else if (l1 > l2) return false;
else {
int dist1Right = Math.abs(r1 - x);
int dist2Right = Math.abs(r2 - x);
if (dist1Right < dist2Right) return true;
else if (dist1Right > dist2Right) return false;
else return r1 < r2;
}
}
}
public static void main(String[] args) {
System.out.println(findClosestElements(new int[]{1,2,3,4,5}, 4, 3)); // [1, 2, 3, 4]
}
}
Line Notes
int n = arr.length;Get array length for window iteration
for (int start = 0; start <= n - k; start++)Loop over all windows of size k
if (isCloser(left, right, prevLeft, prevRight, x))Update best window start index if current window is closer
List<Integer> result = new ArrayList<>();Prepare list to return the closest elements
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
bool isCloser(int l1, int r1, int l2, int r2, int x) {
int dist1Left = abs(l1 - x);
int dist2Left = abs(l2 - x);
if (dist1Left < dist2Left) return true;
else if (dist1Left > dist2Left) return false;
else {
if (l1 < l2) return true;
else if (l1 > l2) return false;
else {
int dist1Right = abs(r1 - x);
int dist2Right = abs(r2 - x);
if (dist1Right < dist2Right) return true;
else if (dist1Right > dist2Right) return false;
else return r1 < r2;
}
}
}
vector<int> findClosestElements(vector<int>& arr, int k, int x) {
int n = arr.size();
int bestStart = 0;
for (int start = 0; start <= n - k; start++) {
int left = arr[start];
int right = arr[start + k - 1];
if (start == 0) {
bestStart = 0;
continue;
}
int prevLeft = arr[bestStart];
int prevRight = arr[bestStart + k - 1];
if (isCloser(left, right, prevLeft, prevRight, x)) {
bestStart = start;
}
}
return vector<int>(arr.begin() + bestStart, arr.begin() + bestStart + k);
}
int main() {
vector<int> arr = {1,2,3,4,5};
vector<int> res = findClosestElements(arr, 4, 3);
for (int num : res) cout << num << ' ';
cout << endl;
return 0;
}
Line Notes
int n = arr.size();Determine array size for iteration limits
for (int start = 0; start <= n - k; start++)Check every window of size k
if (isCloser(left, right, prevLeft, prevRight, x))Update best window if current window is closer
return vector<int>(arr.begin() + bestStart, arr.begin() + bestStart + k);Return the closest k elements
function isCloser(l1, r1, l2, r2, x) {
const dist1Left = Math.abs(l1 - x);
const dist2Left = Math.abs(l2 - x);
if (dist1Left < dist2Left) return true;
else if (dist1Left > dist2Left) return false;
else {
if (l1 < l2) return true;
else if (l1 > l2) return false;
else {
const dist1Right = Math.abs(r1 - x);
const dist2Right = Math.abs(r2 - x);
if (dist1Right < dist2Right) return true;
else if (dist1Right > dist2Right) return false;
else return r1 < r2;
}
}
}
function findClosestElements(arr, k, x) {
let n = arr.length;
let bestStart = 0;
for (let start = 0; start <= n - k; start++) {
let left = arr[start];
let right = arr[start + k - 1];
if (start === 0) {
bestStart = 0;
continue;
}
let prevLeft = arr[bestStart];
let prevRight = arr[bestStart + k - 1];
if (isCloser(left, right, prevLeft, prevRight, x)) {
bestStart = start;
}
}
return arr.slice(bestStart, bestStart + k);
}
// Test
console.log(findClosestElements([1,2,3,4,5], 4, 3)); // [1,2,3,4]
Line Notes
let n = arr.length;Get array length to know how many windows to check
for (let start = 0; start <= n - k; start++)Iterate over all possible windows of size k
if (isCloser(left, right, prevLeft, prevRight, x))Update best window start if current window is closer
return arr.slice(bestStart, bestStart + k);Return the closest k elements
We check all n-k+1 windows, each of size k, so roughly O(n*k). Space is O(k) for the output.
💡 For n=1000 and k=10, this means about 10,000 operations, which is slow for large n.
Interview Verdict: TLE / Inefficient for large inputs
This approach is too slow for large arrays but is useful to understand the problem and correctness.