diff --git a/linked-list-cycle/crumbs22.cpp b/linked-list-cycle/crumbs22.cpp new file mode 100644 index 000000000..1e46e8651 --- /dev/null +++ b/linked-list-cycle/crumbs22.cpp @@ -0,0 +1,34 @@ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * ListNode *next; + * ListNode(int x) : val(x), next(NULL) {} + * }; + */ + +/* + 해시 (std::unordered_set<>)에 주소를 기록해두고, + 다음 노드로 넘어가기 전에 이미 집합에 들어있는지 검사 + + 공간복잡도는 O(n)으로, 해시에 대한 메모리를 사용 + 시간복잡도는 O(n) +*/ + + +class Solution { +public: + bool hasCycle(ListNode *head) { + std::unordered_set visited; + ListNode* cur = head; + + while (cur) { + if (visited.count(cur) == 1) // 이미 본 노드면 cycle이 존재 + return (true) ; + + visited.insert(cur); // 방문 기록 + cur = cur->next; + } + return (false); // 끝까지 돌았으나 순환이 없는 경우에만 cycle이 존재하지 않음 + } +}; diff --git a/maximum-product-subarray/crumbs22.cpp b/maximum-product-subarray/crumbs22.cpp new file mode 100644 index 000000000..2208190eb --- /dev/null +++ b/maximum-product-subarray/crumbs22.cpp @@ -0,0 +1,24 @@ +/* + 한 번의 순회로 위치마다의 최대곱과 최소 곱을 갱신 + 시간복잡도는 O(n), 공간복잡도는 O(1) +*/ +class Solution { + public: + int maxProduct(vector& nums) { + int ans = nums[0]; + int curMax = nums[0]; + int curMin = nums[0]; + + // 1번째부터 마지막까지 순회 + for (int i = 1; i < nums.size(); i++) { + // 음수를 곱하면 현재까지의 최대 곱이 최소가 되고, 최소 곱은 최대 곱으로 뒤바뀜 + if (nums[i] < 0) + swap(curMax, curMin); + + curMax = max(nums[i], curMax * nums[i]); + curMin = min(nums[i], curMin * nums[i]); + ans = max(ans, curMax); + } + return (ans); + } + }; diff --git a/pacific-atlantic-water-flow/crumbs22.cpp b/pacific-atlantic-water-flow/crumbs22.cpp new file mode 100644 index 000000000..da6ebeaff --- /dev/null +++ b/pacific-atlantic-water-flow/crumbs22.cpp @@ -0,0 +1,77 @@ +class Solution { + public: + + vector> pacificAtlantic(vector>& heights) { + int m = heights.size(); + if (m == 0) + return {}; + int n = heights[0].size(); + if (n == 0) + return {}; + + vector> reachP(m, vector(n, false)); + vector> reachA(m, vector(n, false)); + queue> qP, qA; + + + // Pacific 경계 초기화 + for (int i = 0; i < m; i++) { + reachP[i][0] = true; + qP.emplace(i, 0); // Pacific 경계에서 시작할 좌표로 큐에 등록. 이후 이 좌표들은 BFS의 출발점이 됨 + } + for (int j = 0; j < n; j++) { + reachP[0][j] = true; + qP.emplace(0, j); + } + + // Atlantic 경계 초기화 + for (int i = 0; i < m; i++) { + reachA[i][n - 1] = true; + qA.emplace(i, n - 1); + } + for (int j = 0; j < n; j++) { + reachA[m - 1][j] = true; + qA.emplace(m - 1, j); + } + + // 각 경계에 대한 bfs + bfs(heights, qP, reachP); + bfs(heights, qA, reachA); + + // 두 경계에 모두 도달 가능한 셀 수집 + vector> ans; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (reachP[i][j] && reachA[i][j]) { + ans.push_back({i, j}); + } + } + } + return (ans); + } + + void bfs(const vector>& h, queue>& q, vector>& reach) { + int m = h.size(); + int n = h[0].size(); + int dr[4] = {1, -1, 0, 0}; + int dc[4] = {0, 0, 1, -1}; + + while (!q.empty()) { + auto [r,c] = q.front(); + q.pop(); + for (int d = 0; d < 4; d++) { + int nr = r + dr[d]; + int nc = c + dc[d]; + + if (nr < 0 || nr >= m || nc < 0 || nc >= n) + continue ; + if (reach[nr][nc]) + continue ; + if (h[nr][nc] < h[r][c]) + continue ; + reach[nr][nc] = true; + q.emplace(nr, nc); + } + } + } + }; diff --git a/sum-of-two-integers/crumbs22.cpp b/sum-of-two-integers/crumbs22.cpp new file mode 100644 index 000000000..2cc8c1b8d --- /dev/null +++ b/sum-of-two-integers/crumbs22.cpp @@ -0,0 +1,24 @@ +/* + - 각 비트 중 하나만 1일 때 1이 되므로 XOR연산 활용 + - 각 비트 둘 다 1일 때 올림수가 발생하므로 &연산 활용 + - a는 이제까지의 합 비트가 되고 + b는 다음 자리에서 더해줘야 될 올림 비트가 됨. + 올림 비트 b가 0이 될 때까지 반복 + 시간 복잡도는 O(1), 공간 복잡도는 O(1) +*/ + +class Solution { + public: + int getSum(int a, int b) { + + while (b != 0) { + // 올림수 계산 + int carry = (a & b) << 1; + // 올림 무시한 합 비트 계산 + a = a ^ b; + // 다음 반복에 carry 더해주기 + b = carry; + } + return (a); + } + };