[Leetcode/C++] 122_Best Time to Buy and Sell Stock II

이수진·2022년 2월 2일

문제는 다음과 같습니다.

처음에는 dp로 접근해서 배열에 모든 경우의 수에 대해 저장하는 방법으로 풀었다가 겁나게 삽질했다 ㅠㅠ
2차원 배열에 i번째 날에 buy j번째 날에 sell 하는 식으로 일일이 구하고 뭐 그런식으로 했지만 이게 아닌 것 같아서 다른 방법을 찾았다.

일단, 몇몇의 예시를 써놓고 방법을 찾았는데
그림으로 입력받은 금액의 그래프를 그려보니 쉽게 문제를 풀 수 있었다.

먼저, 1번의 예시처럼 금액이 오르락내리락을 반복하는 경우를 보면,
구하는 최대 이익은 "증가하는 직선의 y좌표 값"을 구하면 된다.
여기서 "증가하는 직선"이란 ↗️이 방향의 직선을 의미한다.
왜냐하면 주식을 먼저 사고 이후에 팔아야하므로 그리고 이 이익이라는것은 양수값이어야만 하니까, ↗️ 이 방향 그래프의 y절편의 최대-최소값이 이익이 된다.
1번의 예시를 보면, ↗️이 방향 그래프가 나타나는 부분은 (1,5) 그리고 (3,6) 두 가지 경우이며, 따라서 4+3=7이 답이 된다.

그리고 두 번째 예시를 살펴보면 이 경우는 부분적으로 계속 증가하는 경우이다. 이 경우가 예외라고 생각할 수도 있겠지만, 1번 경우를 응용하면 된다.
즉, ↗️이 방향 그래프가 연속적으로 나온다고 생각하면 된다.

원래 2번과 같은 경우의 답은 (1, 100) 이어서 100-1=99가 주어진 답의 풀이가 된다.
하지만 이는 ↗️방향 그래프가 두 개인 (1, 5), (5, 100)이 두 번 있다고 생각하면 되고,
이는 4+95=99로 답과 같게 나오게 된다.

이 두 번째 예시 때문에,
for문 코드를 살펴보면

        for(int i=1; i<prices.size(); i++){
            buy_cost=min(buy_cost, prices[i]);
            if(prices[i]>buy_cost){
                profit+=(prices[i]-buy_cost);
                buy_cost=prices[i];
            }
        }

다음과 같은데,
여기서 if문안의 buy_cost가 prices[i+1]이 아니라 buy_cost=prices[i]가 된다.

어차피, buy_cost=min(buy_cost, prices[i])에서 더 작은 값으로 갱신해주기때문에 상관이 없게 된다.

전체 코드는 다음과 같다.

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int buy_cost=prices[0];
        int profit=0;
        
        for(int i=1; i<prices.size(); i++){
            buy_cost=min(buy_cost, prices[i]);
            if(prices[i]>buy_cost){
                profit+=(prices[i]-buy_cost);
                buy_cost=prices[i];
            }
        }
        return profit;
    }
};


2/8 화요일 복습)

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        // 증가하는 구간만 다 구하면 됨
        int buy_cost = prices[0];
        int profit, total=0;
        for(int i=1; i<prices.size(); i++){
            buy_cost = min(buy_cost, prices[i]);
            profit = max(0, prices[i]-(buy_cost)); // 음수여도 0을 더할 수 있도록
            total += profit;
            buy_cost = prices[i]; // buy_cost 갱신시키기
        }
        return total;
    }
};
profile
꾸준히, 열심히, 그리고 잘하자

0개의 댓글