Skip to content

[sungjinwi] Week07 solution #1478

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions longest-substring-without-repeating-characters/sungjinwi.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
풀이 :
슬라이딩 윈도우 기법을 사용해서 풀이
right가 현재까지 문자열에 포함되지 않는 문자면 right의 문자를 set에 추가 후 right 증가, 문자열길이를 늘리고 최대길이와 비교해서 업데이트
이미 문자열에 포함되는 문자면 left의 문자를 set에서 제거 후 left 증가

문자열 길이 : N

TC : O(N)
문자열 전체에 대해 1회 순회

SC : O(N)
해시테이블 unordered_set의 크기는 문자열 길이에 비례

추가적인 최적화 방법 :
int lastIdx[256] 선언하고 아스키코드 위치에 마지막으로 해당 문자가 나온 인덱스를 저장한다
ex) a가 10번쨰 인덱스에서 나오면 lastIdx['a'] = 10;
나중에 중복되는 문자를 만나는 경우 left를 1씩 전진시키는 것이 아니라 중복된 문자의 마지막 바로 다음으로 left를 업데이트
*/

#include <unordered_set>

class Solution {
public:
int lengthOfLongestSubstring(string s) {
int ans = 0;
int left = 0, right = 0;
unordered_set<char> lookup;

while (right < s.size())
{
if (lookup.find(s[right]) == lookup.end()) {
ans = max(ans, right - left + 1);
lookup.insert(s[right]);
right++;
}
else {
lookup.erase(s[left]);
left++;
}
}

return ans;
}
};
43 changes: 43 additions & 0 deletions number-of-islands/sungjinwi.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
풀이 :
grid를 순회하면서 '1'을 만나면 상하좌우를 dfs를 통해 이미 탐색한 땅이라는 뜻으로 '$'로 변경하고
새로운 땅을 만날때마다 cnt 증가

grid 크기 M * N

TC : O(M * N)
dfs 호출은 grid의 크기에 비례

SC : O(M * N)
dfs 호출 스택도 grid의 크기에 비례례
*/

#include <vector>
using namesapce std;

class Solution {
public:
int numIslands(vector<vector<char>>& grid) {
int cnt = 0;

for (int i = 0; i < grid.size(); i++) {
for (int j = 0; j < grid[0].size(); j++) {
if (grid[i][j] == '1') {
dfs(i, j, grid);
cnt++;
}
}
}
return (cnt);
}

void dfs(int row, int col, vector<vector<char>>& grid) {
if (row < 0 || row >= grid.size() || col < 0 || col >= grid[0].size() || grid[row][col] != '1')
return ;
grid[row][col] = '$';
dfs(row + 1, col, grid);
dfs(row - 1, col, grid);
dfs(row, col + 1, grid);
dfs(row, col - 1, grid);
}
};
62 changes: 62 additions & 0 deletions reverse-linked-list/sungjinwi.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
풀이 :
linked-list를 순회하며 stack에 차례대로 push하고 다 넣은 후
pop하면서 역순으로 연결해준다

노드의 개수 : N

TC : O(N)
총 2회 while 반복문 O(N + N)

SC : O(N)
스택은 노드의 개수에 비례
*/

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/

#include <stack>
using namespace std;

struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};

class Solution {
public:
ListNode* reverseList(ListNode* head) {
stack<ListNode*> st;
ListNode dummy;
ListNode* prv = &dummy;
ListNode* cur;

while (head)
{
st.push(head);
head = head->next;
}

while (!st.empty())
{
cur = st.top();
prv->next = cur;
prv = cur;
st.pop();
}
prv->next = nullptr;

return dummy.next;
}
};
64 changes: 64 additions & 0 deletions set-matrix-zeroes/sungjinwi.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
풀이 :
row0과 col0 을 해당 줄이 0이 되는지 지표로 사용해서 공간복잡도 O(1)을 달성할 것이다

1. row0과 col0 중에 0이 존재하는지 미리 확인하고 변수에 저장

2. matrix를 순회(첫행, 첫열 제외)하면서 0인 칸을 만나면 해당 정보를 첫행, 첫열에 저장

3. 저장된 정보를 바탕으로 matrix 업데이트

4. 변수에 담았던 첫행, 첫열에 0이 존재하는가 바탕으로 업데이트

matrix 크기 : M * N

TC : O(M * N)

SC : O(1)
*/

#include <vector>
using namespace std;

class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
bool firstRowZero = false, firstColZero = false;

int nRows = matrix.size();
int nCols = matrix[0].size();

for (int i = 0; i < nRows; i++)
if (matrix[i][0] == 0)
firstColZero = true;

for (int j = 0; j < nCols; j++)
if (matrix[0][j] == 0)
firstRowZero = true;

for (int i = 1; i <nRows; i++) {
for (int j = 1; j < nCols; j++) {
if (matrix[i][j] == 0) {
matrix[i][0] = 0;
matrix[0][j] = 0;
}
}
}

for (int i = 1; i < nRows; i++) {
for (int j = 1; j < nCols; j++)
if (matrix[i][0] == 0 || matrix[0][j] == 0)
matrix[i][j] = 0;
}

if (firstRowZero) {
for (int i = 0; i < nCols; i++)
matrix[0][i] = 0;
}

if (firstColZero) {
for (int i = 0; i < nRows; i++)
matrix[i][0] = 0;
}
}
};
31 changes: 31 additions & 0 deletions unique-paths/sungjinwi.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
풀이 :
특정 칸에 오는 방법은 왼쪽에서 오거나 위에서 오거나 둘 중 하나이므로 두 곳의 unique path 개수를 더하면 구할 수 있다
한 row 만들고 두번쨰 줄부터 그 이전 값(위에서 오는 개수)과 그 전 index의 값(왼쪽에서 오는 개수)를 더하면서 반복한다
최종적으로 row의 가장 오른쪽 값 return

row크기 = M, col 크기 = N

TC : O(M * N)
모든 칸에 대해 순회

SC : O(N)
한 row만큼 메모리 할당
*/

#include <vector>
using namespace std;

class Solution {
public:
int uniquePaths(int m, int n) {
vector<int> row(n, 1);

for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
row[j] = row[j] + row[j - 1];
}
}
return row[n - 1];
}
};