@@ -31,3 +31,100 @@ def is_palindrome(s):
3131 palindrome_set .add (substr )
3232 answer += 1
3333 return answer
34+
35+
36+ class SolutionDPSet :
37+ def countSubstrings (self , s : str ) -> int :
38+ """
39+ Intuition:
40+ 위 solution에서 중복을 제거할 수 있는 방법은,
41+ start : end 길이를 갖는 substring에서
42+ s[start] == s[end]이고, start + 1 : end - 1의
43+ substring이 palindrome이라면, 이 substring은
44+ palindrome이라고 볼 수 있다.
45+
46+ Time Complexity:
47+ O(N^2):
48+ DP로 인해 palindrome을 찾는 함수가 대략
49+ 상수의 시간복잡도가 걸린다고 볼 수 있다.
50+ 따라서 substring을 만드는 이중 루프에서의
51+ 시간복잡도가 걸릴 수 있다고 보면 된다.
52+
53+ Space Complexity:
54+ O(N^2):
55+ dp set에 index set을 저장하는데, 최악의 경우
56+ index set은 N^2개만큼 저장될 수 있다.
57+
58+ Key takeaway:
59+ dp를 이용해서 푸는 방식에 대해 익숙해져야겠다.
60+
61+ 의문점은 leetcode에서 bruteforce보다 시간이 더 소요되었다는 것이다.
62+ 아마 list 크기를 초과할 경우에 append를 할 경우,
63+ 리스트 크기를 2배만큼 늘리는 list doubling 방식이
64+ set에도 적용이 되어 느려진 것으로 보인다.
65+ """
66+ dp = set ()
67+
68+
69+ def is_palindrome (start , end ):
70+ while start < end :
71+ if s [start ] != s [end ]:
72+ return False
73+ if (start , end ) in dp :
74+ return True
75+ start += 1
76+ end -= 1
77+
78+ return True
79+
80+
81+ answer = 0
82+ for length in range (1 , len (s ) + 1 ):
83+ for start in range (0 , len (s ) - length + 1 ):
84+ end = start + length - 1
85+ if (start , end ) in dp or is_palindrome (start , end ):
86+ dp .add ((start , end ))
87+ answer += 1
88+ return answer
89+
90+
91+ class SolutionDPList :
92+ def countSubstrings (self , s : str ) -> int :
93+ """
94+ Intuition:
95+ DP solution에서 set로 저장하지 않고,
96+ 이중 리스트로 저장하는 것으로 수정했다.
97+ length = 2인 경우에는 start와 end만 동일하면
98+ palindrome으로 판단할 수 있어 조건을 추가했다.
99+
100+ Time Complexity:
101+ O(N^2):
102+ DP로 인해 palindrome을 찾는 함수가 대략
103+ 상수의 시간복잡도가 걸린다고 볼 수 있다.
104+ 따라서 substring을 만드는 이중 루프에서의
105+ 시간복잡도가 걸릴 수 있다고 보면 된다.
106+
107+ Space Complexity:
108+ O(N^2):
109+ dp 리스트에 substring 이중 리스트를 저장하므로
110+ N^2개만큼 저장될 수 있다.
111+
112+ Key takeaway:
113+ 이 방법이 가장 빠르게 동작했다.
114+ """
115+ dp = [[False for _ in s ] for _ in s ]
116+ answer = 0
117+
118+ for i in range (len (s )):
119+ dp [i ][i ] = True
120+ answer += 1
121+
122+ for length in range (2 , len (s ) + 1 ):
123+ for start in range (len (s ) - length + 1 ):
124+ end = start + length - 1
125+ if s [start ] == s [end ]:
126+ if length == 2 or dp [start + 1 ][end - 1 ]:
127+ dp [start ][end ] = True
128+ answer += 1
129+
130+ return answer
0 commit comments