02_array_string.cpp

Download
cpp 345 lines 9.7 KB
  1/*
  2 * ๋ฐฐ์—ด๊ณผ ๋ฌธ์ž์—ด (Array and String)
  3 * Two Pointers, Sliding Window, Prefix Sum
  4 *
  5 * ๋ฐฐ์—ด๊ณผ ๋ฌธ์ž์—ด ์ฒ˜๋ฆฌ์˜ ํ•ต์‹ฌ ๊ธฐ๋ฒ•๋“ค์ž…๋‹ˆ๋‹ค.
  6 */
  7
  8#include <iostream>
  9#include <vector>
 10#include <string>
 11#include <unordered_map>
 12#include <unordered_set>
 13#include <algorithm>
 14#include <climits>
 15
 16using namespace std;
 17
 18// =============================================================================
 19// 1. ํˆฌ ํฌ์ธํ„ฐ (Two Pointers)
 20// =============================================================================
 21
 22// ์ •๋ ฌ๋œ ๋ฐฐ์—ด์—์„œ ๋‘ ์ˆ˜์˜ ํ•ฉ
 23pair<int, int> twoSumSorted(const vector<int>& arr, int target) {
 24    int left = 0, right = arr.size() - 1;
 25
 26    while (left < right) {
 27        int sum = arr[left] + arr[right];
 28        if (sum == target)
 29            return {left, right};
 30        else if (sum < target)
 31            left++;
 32        else
 33            right--;
 34    }
 35
 36    return {-1, -1};
 37}
 38
 39// ๋ฌผ ๋‹ด๊ธฐ (Container With Most Water)
 40int maxArea(const vector<int>& height) {
 41    int left = 0, right = height.size() - 1;
 42    int maxWater = 0;
 43
 44    while (left < right) {
 45        int h = min(height[left], height[right]);
 46        int w = right - left;
 47        maxWater = max(maxWater, h * w);
 48
 49        if (height[left] < height[right])
 50            left++;
 51        else
 52            right--;
 53    }
 54
 55    return maxWater;
 56}
 57
 58// ์„ธ ์ˆ˜์˜ ํ•ฉ
 59vector<vector<int>> threeSum(vector<int>& nums) {
 60    vector<vector<int>> result;
 61    sort(nums.begin(), nums.end());
 62    int n = nums.size();
 63
 64    for (int i = 0; i < n - 2; i++) {
 65        if (i > 0 && nums[i] == nums[i - 1]) continue;
 66
 67        int left = i + 1, right = n - 1;
 68        while (left < right) {
 69            int sum = nums[i] + nums[left] + nums[right];
 70            if (sum == 0) {
 71                result.push_back({nums[i], nums[left], nums[right]});
 72                while (left < right && nums[left] == nums[left + 1]) left++;
 73                while (left < right && nums[right] == nums[right - 1]) right--;
 74                left++;
 75                right--;
 76            } else if (sum < 0) {
 77                left++;
 78            } else {
 79                right--;
 80            }
 81        }
 82    }
 83
 84    return result;
 85}
 86
 87// =============================================================================
 88// 2. ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ (Sliding Window)
 89// =============================================================================
 90
 91// ๊ณ ์ • ํฌ๊ธฐ ์œˆ๋„์šฐ ์ตœ๋Œ€ ํ•ฉ
 92int maxSumWindow(const vector<int>& arr, int k) {
 93    int n = arr.size();
 94    if (n < k) return -1;
 95
 96    int windowSum = 0;
 97    for (int i = 0; i < k; i++) {
 98        windowSum += arr[i];
 99    }
100
101    int maxSum = windowSum;
102    for (int i = k; i < n; i++) {
103        windowSum += arr[i] - arr[i - k];
104        maxSum = max(maxSum, windowSum);
105    }
106
107    return maxSum;
108}
109
110// ์ค‘๋ณต ์—†๋Š” ์ตœ์žฅ ๋ถ€๋ถ„ ๋ฌธ์ž์—ด
111int lengthOfLongestSubstring(const string& s) {
112    unordered_set<char> charSet;
113    int maxLen = 0;
114    int left = 0;
115
116    for (int right = 0; right < (int)s.length(); right++) {
117        while (charSet.count(s[right])) {
118            charSet.erase(s[left]);
119            left++;
120        }
121        charSet.insert(s[right]);
122        maxLen = max(maxLen, right - left + 1);
123    }
124
125    return maxLen;
126}
127
128// ํ•ฉ์ด target ์ด์ƒ์ธ ์ตœ์†Œ ๊ธธ์ด ๋ถ€๋ถ„ ๋ฐฐ์—ด
129int minSubArrayLen(int target, const vector<int>& nums) {
130    int n = nums.size();
131    int minLen = INT_MAX;
132    int sum = 0;
133    int left = 0;
134
135    for (int right = 0; right < n; right++) {
136        sum += nums[right];
137        while (sum >= target) {
138            minLen = min(minLen, right - left + 1);
139            sum -= nums[left];
140            left++;
141        }
142    }
143
144    return minLen == INT_MAX ? 0 : minLen;
145}
146
147// =============================================================================
148// 3. ํ”„๋ฆฌํ”ฝ์Šค ํ•ฉ (Prefix Sum)
149// =============================================================================
150
151class PrefixSum {
152private:
153    vector<long long> prefix;
154
155public:
156    PrefixSum(const vector<int>& arr) {
157        int n = arr.size();
158        prefix.resize(n + 1, 0);
159        for (int i = 0; i < n; i++) {
160            prefix[i + 1] = prefix[i] + arr[i];
161        }
162    }
163
164    // [left, right] ๊ตฌ๊ฐ„ ํ•ฉ
165    long long rangeSum(int left, int right) {
166        return prefix[right + 1] - prefix[left];
167    }
168};
169
170// ํ•ฉ์ด k์ธ ๋ถ€๋ถ„ ๋ฐฐ์—ด ๊ฐœ์ˆ˜
171int subarraySum(const vector<int>& nums, int k) {
172    unordered_map<int, int> prefixCount;
173    prefixCount[0] = 1;
174    int sum = 0;
175    int count = 0;
176
177    for (int num : nums) {
178        sum += num;
179        if (prefixCount.count(sum - k)) {
180            count += prefixCount[sum - k];
181        }
182        prefixCount[sum]++;
183    }
184
185    return count;
186}
187
188// =============================================================================
189// 4. ์นด๋ฐ์ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜ (Kadane's Algorithm)
190// =============================================================================
191
192int maxSubArray(const vector<int>& nums) {
193    int maxSum = nums[0];
194    int currentSum = nums[0];
195
196    for (size_t i = 1; i < nums.size(); i++) {
197        currentSum = max(nums[i], currentSum + nums[i]);
198        maxSum = max(maxSum, currentSum);
199    }
200
201    return maxSum;
202}
203
204// ์ตœ๋Œ€ ๋ถ€๋ถ„ ๋ฐฐ์—ด์˜ ์ธ๋ฑ์Šค๋„ ๋ฐ˜ํ™˜
205tuple<int, int, int> maxSubArrayWithIndices(const vector<int>& nums) {
206    int maxSum = nums[0];
207    int currentSum = nums[0];
208    int start = 0, end = 0, tempStart = 0;
209
210    for (size_t i = 1; i < nums.size(); i++) {
211        if (nums[i] > currentSum + nums[i]) {
212            currentSum = nums[i];
213            tempStart = i;
214        } else {
215            currentSum += nums[i];
216        }
217
218        if (currentSum > maxSum) {
219            maxSum = currentSum;
220            start = tempStart;
221            end = i;
222        }
223    }
224
225    return {maxSum, start, end};
226}
227
228// =============================================================================
229// 5. ๋ฌธ์ž์—ด ์ฒ˜๋ฆฌ
230// =============================================================================
231
232// ํŒฐ๋ฆฐ๋“œ๋กฌ ์ฒดํฌ
233bool isPalindrome(const string& s) {
234    int left = 0, right = s.length() - 1;
235    while (left < right) {
236        if (s[left] != s[right]) return false;
237        left++;
238        right--;
239    }
240    return true;
241}
242
243// ์• ๋„ˆ๊ทธ๋žจ ์ฒดํฌ
244bool isAnagram(const string& s, const string& t) {
245    if (s.length() != t.length()) return false;
246
247    vector<int> count(26, 0);
248    for (size_t i = 0; i < s.length(); i++) {
249        count[s[i] - 'a']++;
250        count[t[i] - 'a']--;
251    }
252
253    for (int c : count) {
254        if (c != 0) return false;
255    }
256    return true;
257}
258
259// ๋ฌธ์ž์—ด ์••์ถ•
260string compress(const string& s) {
261    if (s.empty()) return s;
262
263    string result;
264    int count = 1;
265
266    for (size_t i = 1; i <= s.length(); i++) {
267        if (i < s.length() && s[i] == s[i - 1]) {
268            count++;
269        } else {
270            result += s[i - 1];
271            if (count > 1) {
272                result += to_string(count);
273            }
274            count = 1;
275        }
276    }
277
278    return result.length() < s.length() ? result : s;
279}
280
281// =============================================================================
282// ํ…Œ์ŠคํŠธ
283// =============================================================================
284
285int main() {
286    cout << "============================================================" << endl;
287    cout << "๋ฐฐ์—ด๊ณผ ๋ฌธ์ž์—ด ์˜ˆ์ œ" << endl;
288    cout << "============================================================" << endl;
289
290    // 1. ํˆฌ ํฌ์ธํ„ฐ
291    cout << "\n[1] ํˆฌ ํฌ์ธํ„ฐ" << endl;
292    vector<int> sorted = {1, 2, 3, 4, 6};
293    auto [idx1, idx2] = twoSumSorted(sorted, 6);
294    cout << "    ๋ฐฐ์—ด: [1,2,3,4,6], ํƒ€๊ฒŸ: 6" << endl;
295    cout << "    ์ธ๋ฑ์Šค: (" << idx1 << ", " << idx2 << ")" << endl;
296
297    vector<int> heights = {1, 8, 6, 2, 5, 4, 8, 3, 7};
298    cout << "    ๋ฌผ ๋‹ด๊ธฐ: " << maxArea(heights) << endl;
299
300    // 2. ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ
301    cout << "\n[2] ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ" << endl;
302    vector<int> arr = {1, 4, 2, 10, 23, 3, 1, 0, 20};
303    cout << "    ํฌ๊ธฐ 4 ์œˆ๋„์šฐ ์ตœ๋Œ€ ํ•ฉ: " << maxSumWindow(arr, 4) << endl;
304
305    cout << "    \"abcabcbb\" ์ตœ์žฅ ๋ถ€๋ถ„ ๋ฌธ์ž์—ด: " << lengthOfLongestSubstring("abcabcbb") << endl;
306
307    vector<int> nums = {2, 3, 1, 2, 4, 3};
308    cout << "    ํ•ฉ >= 7 ์ตœ์†Œ ๊ธธ์ด: " << minSubArrayLen(7, nums) << endl;
309
310    // 3. ํ”„๋ฆฌํ”ฝ์Šค ํ•ฉ
311    cout << "\n[3] ํ”„๋ฆฌํ”ฝ์Šค ํ•ฉ" << endl;
312    vector<int> prefixArr = {1, 2, 3, 4, 5};
313    PrefixSum ps(prefixArr);
314    cout << "    ๋ฐฐ์—ด: [1,2,3,4,5]" << endl;
315    cout << "    [1,3] ๊ตฌ๊ฐ„ ํ•ฉ: " << ps.rangeSum(1, 3) << endl;
316
317    vector<int> subarr = {1, 1, 1};
318    cout << "    ํ•ฉ์ด 2์ธ ๋ถ€๋ถ„ ๋ฐฐ์—ด ๊ฐœ์ˆ˜: " << subarraySum(subarr, 2) << endl;
319
320    // 4. ์นด๋ฐ์ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜
321    cout << "\n[4] ์นด๋ฐ์ธ ์•Œ๊ณ ๋ฆฌ์ฆ˜" << endl;
322    vector<int> kadane = {-2, 1, -3, 4, -1, 2, 1, -5, 4};
323    cout << "    ๋ฐฐ์—ด: [-2,1,-3,4,-1,2,1,-5,4]" << endl;
324    cout << "    ์ตœ๋Œ€ ๋ถ€๋ถ„ ๋ฐฐ์—ด ํ•ฉ: " << maxSubArray(kadane) << endl;
325
326    // 5. ๋ฌธ์ž์—ด ์ฒ˜๋ฆฌ
327    cout << "\n[5] ๋ฌธ์ž์—ด ์ฒ˜๋ฆฌ" << endl;
328    cout << "    \"racecar\" ํŒฐ๋ฆฐ๋“œ๋กฌ: " << (isPalindrome("racecar") ? "์˜ˆ" : "์•„๋‹ˆ์˜ค") << endl;
329    cout << "    \"anagram\"/\"nagaram\" ์• ๋„ˆ๊ทธ๋žจ: " << (isAnagram("anagram", "nagaram") ? "์˜ˆ" : "์•„๋‹ˆ์˜ค") << endl;
330    cout << "    \"aabcccccaaa\" ์••์ถ•: " << compress("aabcccccaaa") << endl;
331
332    // 6. ๋ณต์žก๋„ ์š”์•ฝ
333    cout << "\n[6] ๋ณต์žก๋„ ์š”์•ฝ" << endl;
334    cout << "    | ์•Œ๊ณ ๋ฆฌ์ฆ˜        | ์‹œ๊ฐ„๋ณต์žก๋„ |" << endl;
335    cout << "    |-----------------|------------|" << endl;
336    cout << "    | ํˆฌ ํฌ์ธํ„ฐ       | O(n)       |" << endl;
337    cout << "    | ์Šฌ๋ผ์ด๋”ฉ ์œˆ๋„์šฐ | O(n)       |" << endl;
338    cout << "    | ํ”„๋ฆฌํ”ฝ์Šค ํ•ฉ     | O(1) ์ฟผ๋ฆฌ  |" << endl;
339    cout << "    | ์นด๋ฐ์ธ          | O(n)       |" << endl;
340
341    cout << "\n============================================================" << endl;
342
343    return 0;
344}