알고리즘 문제 풀이: 제곱 정렬, 최소 부분 배열, 나선형 행렬

997. 정렬된 배열의 제곱 계산

입력된 비내림차순 정수 배열의 각 원소 제곱값을 오름차순으로 반환하는 문제입니다. 원소에는 음수가 포함될 수 있습니다.

  • 무차별 대입 방식: 각 원소의 제곱을 계산한 후 Arrays.sort()로 정렬합니다.
  • 양방향 포인터 방식: 제곱값이 가장 큰 값이 배열 양 끝에 위치한다는 특성을 활용합니다. 두 포인터를 배열 양 끝에 두고 비교하며 결과 배열의 끝부터 채워갑니다.

public class SquaresCalculator {
    public int[] sortedSquares(int[] nums) {
        int length = nums.length;
        int left = 0, right = length - 1;
        int[] result = new int[length];
        int pos = length - 1;
        
        while (left <= right) {
            int leftSquare = nums[left] * nums[left];
            int rightSquare = nums[right] * nums[right];
            
            if (leftSquare > rightSquare) {
                result[pos--] = leftSquare;
                left++;
            } else {
                result[pos--] = rightSquare;
                right--;
            }
        }
        return result;
    }
}

209. 최소 길이 부분 배열 찾기

주어진 배열에서 합이 목표값 이상이 되는 최소 길이 연속 부분 배열을 찾아야 합니다.

  • 슬라이딩 윈도우 기법: 시작과 끝 포인터를 사용하여 윈도우 크기를 동적으로 조절합니다.

public class SubarrayFinder {
    public int minSubArrayLen(int target, int[] nums) {
        int minLength = Integer.MAX_VALUE;
        int currentSum = 0;
        int left = 0, right = 0;
        int n = nums.length;
        
        while (right < n) {
            currentSum += nums[right];
            
            while (currentSum >= target) {
                minLength = Math.min(minLength, right - left + 1);
                currentSum -= nums[left];
                left++;
            }
            right++;
        }
        return (minLength == Integer.MAX_VALUE) ? 0 : minLength;
    }
}

59. 나선형 행렬 생성

1부터 n²까지의 숫자를 시계 방향으로 나선형으로 채우는 문제입니다.

  • 레이어 기반 채우기: 각 바깥쪽 테두리를 반복적으로 채우며, 홀수인 경우 중심값을 별도 처리합니다.

public class SpiralMatrix {
    public int[][] generateMatrix(int n) {
        int[][] result = new int[n][n];
        int value = 1;
        int rowStart = 0, rowEnd = n - 1;
        int colStart = 0, colEnd = n - 1;
        
        while (rowStart <= rowEnd) {
            // 상단 행 채우기 (왼쪽 → 오른쪽)
            for (int i = colStart; i <= colEnd; i++) {
                result[rowStart][i] = value++;
            }
            rowStart++;
            
            // 오른쪽 열 채우기 (상단 → 하단)
            for (int i = rowStart; i <= rowEnd; i++) {
                result[i][colEnd] = value++;
            }
            colEnd--;
            
            // 하단 행 채우기 (오른쪽 → 왼쪽)
            if (rowStart <= rowEnd) {
                for (int i = colEnd; i >= colStart; i--) {
                    result[rowEnd][i] = value++;
                }
                rowEnd--;
            }
            
            // 왼쪽 열 채우기 (하단 → 상단)
            if (colStart <= colEnd) {
                for (int i = rowEnd; i >= rowStart; i--) {
                    result[i][colStart] = value++;
                }
                colStart++;
            }
        }
        return result;
    }
}

태그: 알고리즘 자바 양방향 포인터 슬라이딩 윈도우 행렬 조작

8월 20일 05:50에 게시됨