Skip to content

Commit 04b6cf0

Browse files
committed
feat(dsa): sort colors using two pointers
1 parent 28386d0 commit 04b6cf0

File tree

3 files changed

+212
-0
lines changed

3 files changed

+212
-0
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Sort Colors
2+
3+
Given an array, colors, which contains a combination of the following three elements:
4+
5+
0 (representing red)
6+
1 (representing white)
7+
2 (representing blue)
8+
9+
Sort the array in place so that the elements of the same color are adjacent, with the colors in the order of red, white,
10+
and blue. To improve your problem-solving skills, do not utilize the built-in sort function.
11+
12+
```plain
13+
Example 1:
14+
15+
Input: colors = [2,0,2,1,1,0]
16+
Output: [0,0,1,1,2,2]
17+
```
18+
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
from typing import List
2+
3+
4+
def sort_colors(colors: List[int]) -> List[int]:
5+
"""
6+
Sorts a list of 0s, 1s, and 2s in place
7+
8+
This algorithm uses three pointers: low, mid, and high. The low pointer is used to track the position where the next
9+
0 should be placed, the mid-pointer is used to scan the list, and the high pointer is used to track the position
10+
where the next 2 should be placed.
11+
12+
The algorithm works by iterating through the list with the mid-pointer. If it encounters a 0, it swaps it with the
13+
element at the low index and increments both low and mid. If it encounters a 1, it simply increments mid. If it
14+
encounters a 2, it swaps it with the element at the high index and decrements high (without incrementing mid,
15+
because the swapped element could be a 0 or a 1).
16+
17+
This algorithm has a time complexity of O(n) and a space complexity of O(1), making it efficient for sorting lists
18+
of 0s, 1s, and 2s.
19+
20+
Args:
21+
colors (list): list of 0s, 1s, and 2s
22+
Returns:
23+
list: sorted list of 0s, 1s, and 2s
24+
"""
25+
low, mid, high = 0, 0, len(colors) - 1
26+
27+
while mid <= high:
28+
if colors[mid] == 0:
29+
colors[low], colors[mid] = colors[mid], colors[low]
30+
low += 1
31+
mid += 1
32+
elif colors[mid] == 1:
33+
mid += 1
34+
else:
35+
colors[mid], colors[high] = colors[high], colors[mid]
36+
high -= 1
37+
38+
return colors
39+
40+
def sort_colors_v2(colors: List[int]) -> List[int]:
41+
"""
42+
Sorts a list of 0s, 1s, and 2s in place using two pointers
43+
44+
This algorithm uses two pointers: low and high. The low pointer is used to track the position where the next 0
45+
should be placed, and the high pointer is used to track the position where the next 2 should be placed.
46+
47+
The algorithm works by iterating through the list with the low pointer. If it encounters a 0, it simply increments
48+
low. If it encounters a 2, it decrements high. If it encounters a 1, it swaps it with the element at the high index
49+
and decrements high. This swapping process ensures that all the 1s are placed between the 0s and the 2s.
50+
51+
This algorithm has a time complexity of O(n) and a space complexity of O(1), making it efficient for sorting lists
52+
of 0s, 1s, and 2s using only two pointers.
53+
54+
Args:
55+
colors (list): list of 0s, 1s, and 2s
56+
Returns:
57+
list: sorted list of 0s, 1s, and 2s
58+
"""
59+
red, blue = 0, len(colors) - 1
60+
i = 0
61+
while i <= blue:
62+
if colors[i] == 0:
63+
colors[red], colors[i] = colors[i], colors[red]
64+
red += 1
65+
i += 1
66+
elif colors[i] == 2:
67+
colors[blue], colors[i] = colors[i], colors[blue]
68+
blue -= 1
69+
else:
70+
i += 1
71+
return colors
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
import unittest
2+
from . import sort_colors, sort_colors_v2
3+
4+
5+
class SortColorsV2TestCase(unittest.TestCase):
6+
7+
def test_1(self):
8+
"""should sort colors = [1,0,2,1,2,2] to [0,1,1,2,2,2]"""
9+
colors = [1, 0, 2, 1, 2, 2]
10+
expected = [0, 1, 1, 2, 2, 2]
11+
actual = sort_colors_v2(colors)
12+
self.assertEqual(expected, actual)
13+
14+
def test_2(self):
15+
"""should sort colors = [0,1,1,2,0,2,0,2,1,2] to [0,0,0,1,1,1,2,2,2,2]"""
16+
colors = [0,1,1,2,0,2,0,2,1,2]
17+
expected = [0,0,0,1,1,1,2,2,2,2]
18+
actual = sort_colors_v2(colors)
19+
self.assertEqual(expected, actual)
20+
21+
def test_3(self):
22+
"""should sort colors = [0] to [0]"""
23+
colors = [0]
24+
expected = [0]
25+
actual = sort_colors_v2(colors)
26+
self.assertEqual(expected, actual)
27+
28+
def test_4(self):
29+
"""should sort colors = [0,1,0] to [0,0,1]"""
30+
colors = [0,1,0]
31+
expected = [0,0,1]
32+
actual = sort_colors_v2(colors)
33+
self.assertEqual(expected, actual)
34+
35+
def test_5(self):
36+
"""should sort colors = [1] to [1]"""
37+
colors = [1]
38+
expected = [1]
39+
actual = sort_colors_v2(colors)
40+
self.assertEqual(expected, actual)
41+
42+
def test_6(self):
43+
"""should sort colors = [2,2] to [2,2]"""
44+
colors = [2,2]
45+
expected = [2,2]
46+
actual = sort_colors_v2(colors)
47+
self.assertEqual(expected, actual)
48+
49+
def test_7(self):
50+
"""should sort colors = [1,1,0,2] to [0,1,1,2]"""
51+
colors = [1,1,0,2]
52+
expected = [0,1,1,2]
53+
actual = sort_colors_v2(colors)
54+
self.assertEqual(expected, actual)
55+
56+
def test_8(self):
57+
"""should sort colors = [2,1,1,0,0] to [0,0,1,1,2]"""
58+
colors = [2,1,1,0,0]
59+
expected = [0,0,1,1,2]
60+
actual = sort_colors_v2(colors)
61+
self.assertEqual(expected, actual)
62+
63+
64+
class SortColorsTestCase(unittest.TestCase):
65+
66+
def test_1(self):
67+
"""should sort colors = [1,0,2,1,2,2] to [0,1,1,2,2,2]"""
68+
colors = [1, 0, 2, 1, 2, 2]
69+
expected = [0, 1, 1, 2, 2, 2]
70+
actual = sort_colors(colors)
71+
self.assertEqual(expected, actual)
72+
73+
def test_2(self):
74+
"""should sort colors = [0,1,1,2,0,2,0,2,1,2] to [0,0,0,1,1,1,2,2,2,2]"""
75+
colors = [0,1,1,2,0,2,0,2,1,2]
76+
expected = [0,0,0,1,1,1,2,2,2,2]
77+
actual = sort_colors(colors)
78+
self.assertEqual(expected, actual)
79+
80+
def test_3(self):
81+
"""should sort colors = [0] to [0]"""
82+
colors = [0]
83+
expected = [0]
84+
actual = sort_colors(colors)
85+
self.assertEqual(expected, actual)
86+
87+
def test_4(self):
88+
"""should sort colors = [0,1,0] to [0,0,1]"""
89+
colors = [0,1,0]
90+
expected = [0,0,1]
91+
actual = sort_colors(colors)
92+
self.assertEqual(expected, actual)
93+
94+
def test_5(self):
95+
"""should sort colors = [1] to [1]"""
96+
colors = [1]
97+
expected = [1]
98+
actual = sort_colors(colors)
99+
self.assertEqual(expected, actual)
100+
101+
def test_6(self):
102+
"""should sort colors = [2,2] to [2,2]"""
103+
colors = [2,2]
104+
expected = [2,2]
105+
actual = sort_colors(colors)
106+
self.assertEqual(expected, actual)
107+
108+
def test_7(self):
109+
"""should sort colors = [1,1,0,2] to [0,1,1,2]"""
110+
colors = [1,1,0,2]
111+
expected = [0,1,1,2]
112+
actual = sort_colors(colors)
113+
self.assertEqual(expected, actual)
114+
115+
def test_8(self):
116+
"""should sort colors = [2,1,1,0,0] to [0,0,1,1,2]"""
117+
colors = [2,1,1,0,0]
118+
expected = [0,0,1,1,2]
119+
actual = sort_colors(colors)
120+
self.assertEqual(expected, actual)
121+
122+
if __name__ == '__main__':
123+
unittest.main()

0 commit comments

Comments
 (0)