02_array_string.c

Download
c 346 lines 9.7 KB
  1/*
  2 * ๋ฐฐ์—ด๊ณผ ๋ฌธ์ž์—ด (Array and String)
  3 * Two Pointer, Sliding Window, Prefix Sum
  4 *
  5 * ๋ฐฐ์—ด๊ณผ ๋ฌธ์ž์—ด์„ ํšจ์œจ์ ์œผ๋กœ ๋‹ค๋ฃจ๋Š” ๊ธฐ๋ฒ•๋“ค์ž…๋‹ˆ๋‹ค.
  6 */
  7
  8#include <stdio.h>
  9#include <stdlib.h>
 10#include <string.h>
 11#include <stdbool.h>
 12
 13/* =============================================================================
 14 * 1. ํˆฌ ํฌ์ธํ„ฐ (Two Pointers)
 15 * ============================================================================= */
 16
 17/* ์ •๋ ฌ๋œ ๋ฐฐ์—ด์—์„œ ๋‘ ์ˆ˜์˜ ํ•ฉ์ด target์ธ ์Œ ์ฐพ๊ธฐ */
 18bool two_sum_sorted(int arr[], int n, int target, int* i, int* j) {
 19    int left = 0, right = n - 1;
 20
 21    while (left < right) {
 22        int sum = arr[left] + arr[right];
 23        if (sum == target) {
 24            *i = left;
 25            *j = right;
 26            return true;
 27        } else if (sum < target) {
 28            left++;
 29        } else {
 30            right--;
 31        }
 32    }
 33    return false;
 34}
 35
 36/* ๋ฐฐ์—ด ๋’ค์ง‘๊ธฐ */
 37void reverse_array(int arr[], int left, int right) {
 38    while (left < right) {
 39        int temp = arr[left];
 40        arr[left] = arr[right];
 41        arr[right] = temp;
 42        left++;
 43        right--;
 44    }
 45}
 46
 47/* ์ค‘๋ณต ์ œ๊ฑฐ (์ •๋ ฌ๋œ ๋ฐฐ์—ด) */
 48int remove_duplicates(int arr[], int n) {
 49    if (n == 0) return 0;
 50
 51    int write = 1;
 52    for (int read = 1; read < n; read++) {
 53        if (arr[read] != arr[read - 1]) {
 54            arr[write++] = arr[read];
 55        }
 56    }
 57    return write;
 58}
 59
 60/* =============================================================================
 61 * 2. ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ (Sliding Window)
 62 * ============================================================================= */
 63
 64/* ๊ณ ์ • ํฌ๊ธฐ ์œˆ๋„์šฐ์˜ ์ตœ๋Œ€ ํ•ฉ */
 65int max_sum_subarray(int arr[], int n, int k) {
 66    if (n < k) return -1;
 67
 68    int window_sum = 0;
 69    for (int i = 0; i < k; i++) {
 70        window_sum += arr[i];
 71    }
 72
 73    int max_sum = window_sum;
 74    for (int i = k; i < n; i++) {
 75        window_sum += arr[i] - arr[i - k];
 76        if (window_sum > max_sum) {
 77            max_sum = window_sum;
 78        }
 79    }
 80
 81    return max_sum;
 82}
 83
 84/* ํ•ฉ์ด target ์ด์ƒ์ธ ์ตœ์†Œ ๊ธธ์ด ๋ถ€๋ถ„ ๋ฐฐ์—ด */
 85int min_subarray_len(int arr[], int n, int target) {
 86    int left = 0;
 87    int sum = 0;
 88    int min_len = n + 1;
 89
 90    for (int right = 0; right < n; right++) {
 91        sum += arr[right];
 92
 93        while (sum >= target) {
 94            int len = right - left + 1;
 95            if (len < min_len) min_len = len;
 96            sum -= arr[left++];
 97        }
 98    }
 99
100    return (min_len == n + 1) ? 0 : min_len;
101}
102
103/* ์ตœ๋Œ€ k๊ฐœ 0์„ 1๋กœ ๋ฐ”๊ฟจ์„ ๋•Œ ์—ฐ์† 1์˜ ์ตœ๋Œ€ ๊ธธ์ด */
104int longest_ones(int arr[], int n, int k) {
105    int left = 0;
106    int zeros = 0;
107    int max_len = 0;
108
109    for (int right = 0; right < n; right++) {
110        if (arr[right] == 0) zeros++;
111
112        while (zeros > k) {
113            if (arr[left] == 0) zeros--;
114            left++;
115        }
116
117        int len = right - left + 1;
118        if (len > max_len) max_len = len;
119    }
120
121    return max_len;
122}
123
124/* =============================================================================
125 * 3. ํ”„๋ฆฌํ”ฝ์Šค ํ•ฉ (Prefix Sum)
126 * ============================================================================= */
127
128/* ํ”„๋ฆฌํ”ฝ์Šค ํ•ฉ ๋ฐฐ์—ด ์ƒ์„ฑ */
129int* build_prefix_sum(int arr[], int n) {
130    int* prefix = malloc((n + 1) * sizeof(int));
131    prefix[0] = 0;
132    for (int i = 0; i < n; i++) {
133        prefix[i + 1] = prefix[i] + arr[i];
134    }
135    return prefix;
136}
137
138/* ๊ตฌ๊ฐ„ ํ•ฉ ์ฟผ๋ฆฌ [left, right] */
139int range_sum(int prefix[], int left, int right) {
140    return prefix[right + 1] - prefix[left];
141}
142
143/* 2D ํ”„๋ฆฌํ”ฝ์Šค ํ•ฉ */
144typedef struct {
145    int** prefix;
146    int rows;
147    int cols;
148} PrefixSum2D;
149
150PrefixSum2D* build_prefix_sum_2d(int** matrix, int rows, int cols) {
151    PrefixSum2D* ps = malloc(sizeof(PrefixSum2D));
152    ps->rows = rows;
153    ps->cols = cols;
154    ps->prefix = malloc((rows + 1) * sizeof(int*));
155
156    for (int i = 0; i <= rows; i++) {
157        ps->prefix[i] = calloc(cols + 1, sizeof(int));
158    }
159
160    for (int i = 1; i <= rows; i++) {
161        for (int j = 1; j <= cols; j++) {
162            ps->prefix[i][j] = matrix[i-1][j-1]
163                             + ps->prefix[i-1][j]
164                             + ps->prefix[i][j-1]
165                             - ps->prefix[i-1][j-1];
166        }
167    }
168
169    return ps;
170}
171
172int query_2d(PrefixSum2D* ps, int r1, int c1, int r2, int c2) {
173    return ps->prefix[r2+1][c2+1]
174         - ps->prefix[r1][c2+1]
175         - ps->prefix[r2+1][c1]
176         + ps->prefix[r1][c1];
177}
178
179void free_prefix_sum_2d(PrefixSum2D* ps) {
180    for (int i = 0; i <= ps->rows; i++) {
181        free(ps->prefix[i]);
182    }
183    free(ps->prefix);
184    free(ps);
185}
186
187/* =============================================================================
188 * 4. ๋ฌธ์ž์—ด ์ฒ˜๋ฆฌ
189 * ============================================================================= */
190
191/* ํŒฐ๋ฆฐ๋“œ๋กฌ ๊ฒ€์‚ฌ */
192bool is_palindrome(const char* s) {
193    int left = 0;
194    int right = strlen(s) - 1;
195
196    while (left < right) {
197        if (s[left] != s[right]) return false;
198        left++;
199        right--;
200    }
201    return true;
202}
203
204/* ์• ๋„ˆ๊ทธ๋žจ ๊ฒ€์‚ฌ */
205bool is_anagram(const char* s1, const char* s2) {
206    if (strlen(s1) != strlen(s2)) return false;
207
208    int count[26] = {0};
209
210    for (int i = 0; s1[i]; i++) {
211        count[s1[i] - 'a']++;
212        count[s2[i] - 'a']--;
213    }
214
215    for (int i = 0; i < 26; i++) {
216        if (count[i] != 0) return false;
217    }
218    return true;
219}
220
221/* ๊ฐ€์žฅ ๊ธด ๊ณตํ†ต ์ ‘๋‘์‚ฌ */
222char* longest_common_prefix(char* strs[], int n) {
223    if (n == 0) return "";
224
225    char* prefix = malloc(strlen(strs[0]) + 1);
226    strcpy(prefix, strs[0]);
227
228    for (int i = 1; i < n; i++) {
229        int j = 0;
230        while (prefix[j] && strs[i][j] && prefix[j] == strs[i][j]) {
231            j++;
232        }
233        prefix[j] = '\0';
234    }
235
236    return prefix;
237}
238
239/* =============================================================================
240 * 5. Kadane ์•Œ๊ณ ๋ฆฌ์ฆ˜ (์ตœ๋Œ€ ๋ถ€๋ถ„ ๋ฐฐ์—ด ํ•ฉ)
241 * ============================================================================= */
242
243int max_subarray_sum(int arr[], int n) {
244    int max_ending_here = arr[0];
245    int max_so_far = arr[0];
246
247    for (int i = 1; i < n; i++) {
248        max_ending_here = (arr[i] > max_ending_here + arr[i])
249                        ? arr[i] : max_ending_here + arr[i];
250        if (max_ending_here > max_so_far) {
251            max_so_far = max_ending_here;
252        }
253    }
254
255    return max_so_far;
256}
257
258/* =============================================================================
259 * ํ…Œ์ŠคํŠธ
260 * ============================================================================= */
261
262void print_array(int arr[], int n) {
263    printf("[");
264    for (int i = 0; i < n; i++) {
265        printf("%d", arr[i]);
266        if (i < n - 1) printf(", ");
267    }
268    printf("]");
269}
270
271int main(void) {
272    printf("============================================================\n");
273    printf("๋ฐฐ์—ด๊ณผ ๋ฌธ์ž์—ด (Array and String) ์˜ˆ์ œ\n");
274    printf("============================================================\n");
275
276    /* 1. ํˆฌ ํฌ์ธํ„ฐ */
277    printf("\n[1] ํˆฌ ํฌ์ธํ„ฐ - Two Sum\n");
278    int arr1[] = {2, 7, 11, 15};
279    int i, j;
280    if (two_sum_sorted(arr1, 4, 9, &i, &j)) {
281        printf("    ๋ฐฐ์—ด: [2,7,11,15], target=9\n");
282        printf("    ์ธ๋ฑ์Šค: (%d, %d)\n", i, j);
283    }
284
285    printf("\n[2] ์ค‘๋ณต ์ œ๊ฑฐ\n");
286    int arr2[] = {1, 1, 2, 2, 3, 4, 4};
287    printf("    ์›๋ณธ: ");
288    print_array(arr2, 7);
289    int new_len = remove_duplicates(arr2, 7);
290    printf("\n    ๊ฒฐ๊ณผ: ");
291    print_array(arr2, new_len);
292    printf(" (๊ธธ์ด: %d)\n", new_len);
293
294    /* 2. ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ */
295    printf("\n[3] ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ - ์ตœ๋Œ€ ํ•ฉ\n");
296    int arr3[] = {2, 1, 5, 1, 3, 2};
297    printf("    ๋ฐฐ์—ด: [2,1,5,1,3,2], k=3\n");
298    printf("    ์ตœ๋Œ€ ํ•ฉ: %d\n", max_sum_subarray(arr3, 6, 3));
299
300    printf("\n[4] ํ•ฉ์ด target ์ด์ƒ์ธ ์ตœ์†Œ ๊ธธ์ด\n");
301    int arr4[] = {2, 3, 1, 2, 4, 3};
302    printf("    ๋ฐฐ์—ด: [2,3,1,2,4,3], target=7\n");
303    printf("    ์ตœ์†Œ ๊ธธ์ด: %d\n", min_subarray_len(arr4, 6, 7));
304
305    printf("\n[5] ์ตœ๋Œ€ k๊ฐœ 0โ†’1 ๋ณ€ํ™˜ ํ›„ ์—ฐ์† 1\n");
306    int arr5[] = {1, 1, 0, 0, 1, 1, 1, 0, 1};
307    printf("    ๋ฐฐ์—ด: [1,1,0,0,1,1,1,0,1], k=2\n");
308    printf("    ์ตœ๋Œ€ ๊ธธ์ด: %d\n", longest_ones(arr5, 9, 2));
309
310    /* 3. ํ”„๋ฆฌํ”ฝ์Šค ํ•ฉ */
311    printf("\n[6] ํ”„๋ฆฌํ”ฝ์Šค ํ•ฉ\n");
312    int arr6[] = {1, 2, 3, 4, 5};
313    int* prefix = build_prefix_sum(arr6, 5);
314    printf("    ๋ฐฐ์—ด: [1,2,3,4,5]\n");
315    printf("    ๊ตฌ๊ฐ„ ํ•ฉ [1,3]: %d\n", range_sum(prefix, 1, 3));
316    free(prefix);
317
318    /* 4. ๋ฌธ์ž์—ด */
319    printf("\n[7] ํŒฐ๋ฆฐ๋“œ๋กฌ ๊ฒ€์‚ฌ\n");
320    printf("    'racecar': %s\n", is_palindrome("racecar") ? "true" : "false");
321    printf("    'hello': %s\n", is_palindrome("hello") ? "true" : "false");
322
323    printf("\n[8] ์• ๋„ˆ๊ทธ๋žจ ๊ฒ€์‚ฌ\n");
324    printf("    'listen', 'silent': %s\n",
325           is_anagram("listen", "silent") ? "true" : "false");
326
327    /* 5. Kadane */
328    printf("\n[9] Kadane - ์ตœ๋Œ€ ๋ถ€๋ถ„ ๋ฐฐ์—ด ํ•ฉ\n");
329    int arr9[] = {-2, 1, -3, 4, -1, 2, 1, -5, 4};
330    printf("    ๋ฐฐ์—ด: [-2,1,-3,4,-1,2,1,-5,4]\n");
331    printf("    ์ตœ๋Œ€ ํ•ฉ: %d\n", max_subarray_sum(arr9, 9));
332
333    /* 10. ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์š”์•ฝ */
334    printf("\n[10] ๊ธฐ๋ฒ• ์š”์•ฝ\n");
335    printf("    | ๊ธฐ๋ฒ•           | ์‹œ๊ฐ„๋ณต์žก๋„ | ์šฉ๋„                    |\n");
336    printf("    |----------------|------------|-------------------------|\n");
337    printf("    | ํˆฌ ํฌ์ธํ„ฐ      | O(n)       | ์ •๋ ฌ ๋ฐฐ์—ด, ์–‘๋ ํƒ์ƒ‰    |\n");
338    printf("    | ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ| O(n)       | ์—ฐ์† ๋ถ€๋ถ„ ๋ฐฐ์—ด          |\n");
339    printf("    | ํ”„๋ฆฌํ”ฝ์Šค ํ•ฉ    | O(n)/O(1)  | ๊ตฌ๊ฐ„ ํ•ฉ ์ฟผ๋ฆฌ            |\n");
340    printf("    | Kadane         | O(n)       | ์ตœ๋Œ€ ๋ถ€๋ถ„ ๋ฐฐ์—ด ํ•ฉ       |\n");
341
342    printf("\n============================================================\n");
343
344    return 0;
345}