@@ -31,3 +31,100 @@ def is_palindrome(s):
31
31
palindrome_set .add (substr )
32
32
answer += 1
33
33
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