class Node:def__init__(self, value, next=None) ->None:self.value = valueself.next=nextdef linklist(arr):ifnot arr:returnNone head = Node(arr[0]) current = head for value in arr[1:]: current.next= Node(value) current = current.nextreturn head def print_linklist(head): current = headprint("[", end="")while current:print(current.value, end=", "if current.nextelse"]") current = current.nextprint()
1. Reverse a linked list: Type I
def reverse(head): prev =None curr = head while curr:next= curr.next curr.next= prev prev = curr curr =nextreturn prev h = linklist([1,2,3,4,5])print('Original List:')print_linklist(h)h_reversed = reverse(h)print('Reversed List')print_linklist(h_reversed)
Original List:
[1, 2, 3, 4, 5]
Reversed List
[5, 4, 3, 2, 1]
2. Reverse a linked list: Type II
def reverse_in_between(head, left, right): dummy = Node(0, head) leftPrev = dummy curr = head for _ inrange(left-1): leftPrev = curr curr = curr.next prev =None tail = curr for _ inrange(right - left +1):next= curr.next curr.next= prev prev = curr curr =next leftPrev.next= prev tail.next= curr return dummy.nextif left !=1else prevh = linklist([1,2,3,4,5])print('Original List:')print_linklist(h) h_reversed = reverse_in_between(h,2,4)print('Reversed List between 2 and 4')print_linklist(h_reversed)
Original List:
[1, 2, 3, 4, 5]
Reversed List between 2 and 4
[1, 4, 3, 2, 5]
Arrays, Lists, and Strings
1. Intersection of two arrays
Say you have two arrays. Write a function to get the intersection of the two. For example, if \(A=[2,3,5,6,8]\) and \(B=[4,6,8]\), then the function should return \([6,8]\)
Brute Force
One way to solve this problem is using brute force solution, that is using two nested loops. But this method takes the time complexity of \(O(n\times m)\) given that the lenght of set A is \(n\) and set B is \(m\). And here is how it is:
@time_requireddef intersection_of_two_sets(A,B): set_A =set(A) set_B =set(B) intersection = []for a in set_A:for b in set_B:if a==b: intersection.append(a)return intersectionA = [2,3,5,6,8]B = [4,6,8]print(intersection_of_two_sets(A,B))
Time required: 0.000003 seconds
[6, 8]
Hash Map Approach: In hash map approach, we can solve the same problem but in this case the time and space complexity is \(O(n+m)\)
@time_requireddef intersection_of_two_sets(A,B): set_A =set(A) set_B =set(B)iflen(set_A) <len(set_B):return [a for a in set_A if a in set_B]return [b for b in set_B if b in set_A]A = [2,3,5,6,8]B = [4,6,8]print(intersection_of_two_sets(A,B))
Time required: 0.000003 seconds
[8, 6]
The reason we’re getting \([8,6]\) instead of \([6,8]\) is because sets in Python are unordered collections, meaning that when you convert the lists \(A\) and \(B\) to sets, the order of elements is not preserved. So, when we iterate over set_A or set_A, the order can change.
Better Approach: If we want to maintain the order of the elements in the original list \(A\) or \(B\), we can iterate over the original list directly rather than converting it to a set. Here’s how:
@time_requireddef intersection_of_two_sets(A, B): set_B =set(B) return [a for a in A if a in set_B]A = [2, 3, 5, 6, 8]B = [4, 6, 8]print(intersection_of_two_sets(A, B))
Time required: 0.000002 seconds
[6, 8]
2. Max product of \(k\) elements from an array of \(n\) elements
Say we have an array of size \(n\). We want to find the maximum of the products of \(k\) elements from the array where \(k < n\). For example, if we set \(k=3\) and if we have \(A=[1,2,3,4,5,6]\) then the answer is 120, if we have \(B=[-3,-4,3,5]\) then the answer is 60.
Solution
nlargest and nsmallest are two functions from the heapq library that returns \(n\) largest and \(n\) smallest numbers in decreasing and increasing order, respectively. For example,
import heapqA = [1,2,3,4,5,6]B = [-3,-4,3,5]print('For set {}\n largest 3 numbers {}\n smallest 2 numbers'.format(A,heapq.nlargest(3,A)),heapq.nsmallest(2,A))print('\n')print('For set {}\n largest 3 numbers {}\n smallest 2 numbers'.format(B,heapq.nlargest(3,B)),heapq.nsmallest(2,B))
For set [1, 2, 3, 4, 5, 6]
largest 3 numbers [6, 5, 4]
smallest 2 numbers [1, 2]
For set [-3, -4, 3, 5]
largest 3 numbers [5, 3, -3]
smallest 2 numbers [-4, -3]
Now if all the elements are positive, then the maximum product of \(k=3\) elements would just be the product of the largest three element. However, if the set contains negative numbers like the one in the example, product of the smallest two negative numbers and the first element from the nlargest element that would be the largest.
k =3def max_of_three_element_product(arr): m = heapq.nlargest(k, arr) n = heapq.nsmallest(k-1, arr)returnmax(m[0]*m[1]*m[2], m[0]*n[0]*n[1])A = [1,2,3,4,5,6]B = [-3,-4,3,5]print('Max product of {} elements from set A={} is'.format(k,A), max_of_three_element_product(A))print('Max product of {} elements from set B={} is'.format(k,B), max_of_three_element_product(B))
Max product of 3 elements from set A=[1, 2, 3, 4, 5, 6] is 120
Max product of 3 elements from set B=[-3, -4, 3, 5] is 60
3. Find the \(k\) nearest points from a given point
@time_requireddef knearest(points: list[list[int]], k: int) ->list[list[int]]: dis = []for x in points: d =pow(pow(x[0],2)+pow(x[1],2),0.5) dis.append((x,d)) dis.sort(key=lambda item: item[1])return [x for x,_ in dis[:k]]pts = [[2,-1],[3,2],[4,1],[-1,-1],[-2,2]]k =3print(knearest(pts,k))
Time required: 0.000011 seconds
[[-1, -1], [2, -1], [-2, 2]]
---title: "Data Structure and Algorithms: Basic Programming Hacks"date: "2024-09-11"author: Rafiq Islamcategories: [Programming, Computer Science, DSA, Algorithms]citation: truesearch: trueimage: dsa.jpeglightbox: truelisting: contents: "/../../jobandintern" max-items: 3 type: grid categories: false date-format: full fields: [image, date, title, author, reading-time]format: html: default ipynb: default---<p align="center"> <img src="/_assets/images/uc.jpeg" alt="Post under construction" width="400" height="400"/></p>```{python}#| code-fold: trueimport timedef time_required(func):def wrapper(*args, **kwargs): starting = time.perf_counter() output = func(*args, **kwargs) ending = time.perf_counter() elapsed = ending - startingprint(f'Time required: {elapsed:.6f} seconds')return outputreturn wrapper```## Linked List ```{python}class Node:def__init__(self, value, next=None) ->None:self.value = valueself.next=nextdef linklist(arr):ifnot arr:returnNone head = Node(arr[0]) current = head for value in arr[1:]: current.next= Node(value) current = current.nextreturn head def print_linklist(head): current = headprint("[", end="")while current:print(current.value, end=", "if current.nextelse"]") current = current.nextprint()```### 1. Reverse a linked list: Type I <p align="center"> <img src="/jobandintern/dsa/ll1.png" alt="Post under construction" width="450" height="350"/></p>```{python}#| code-fold: falsedef reverse(head): prev =None curr = head while curr:next= curr.next curr.next= prev prev = curr curr =nextreturn prev h = linklist([1,2,3,4,5])print('Original List:')print_linklist(h)h_reversed = reverse(h)print('Reversed List')print_linklist(h_reversed)```### 2. Reverse a linked list: Type II ```{python}#| code-fold: false def reverse_in_between(head, left, right): dummy = Node(0, head) leftPrev = dummy curr = head for _ inrange(left-1): leftPrev = curr curr = curr.next prev =None tail = curr for _ inrange(right - left +1):next= curr.next curr.next= prev prev = curr curr =next leftPrev.next= prev tail.next= curr return dummy.nextif left !=1else prevh = linklist([1,2,3,4,5])print('Original List:')print_linklist(h) h_reversed = reverse_in_between(h,2,4)print('Reversed List between 2 and 4')print_linklist(h_reversed)```## Arrays, Lists, and Strings ### 1. Intersection of two arrays Say you have two arrays. Write a function to get the intersection of the two. For example, if $A=[2,3,5,6,8]$ and $B=[4,6,8]$, then the function should return $[6,8]$ **Brute Force** <p style="text-align: justify"> One way to solve this problem is using brute force solution, that is using two nested loops. But this method takes the time complexity of $O(n\times m)$ given that the lenght of set A is $n$ and set B is $m$. And here is how it is:</p>```{python}#| code-fold: false@time_requireddef intersection_of_two_sets(A,B): set_A =set(A) set_B =set(B) intersection = []for a in set_A:for b in set_B:if a==b: intersection.append(a)return intersectionA = [2,3,5,6,8]B = [4,6,8]print(intersection_of_two_sets(A,B))```**Hash Map Approach:** In hash map approach, we can solve the same problem but in this case the time and space complexity is $O(n+m)$```{python}#| code-fold: false@time_requireddef intersection_of_two_sets(A,B): set_A =set(A) set_B =set(B)iflen(set_A) <len(set_B):return [a for a in set_A if a in set_B]return [b for b in set_B if b in set_A]A = [2,3,5,6,8]B = [4,6,8]print(intersection_of_two_sets(A,B))```The reason we're getting $[8,6]$ instead of $[6,8]$ is because sets in Python are unordered collections, meaning that when you convert the lists $A$ and $B$ to sets, the order of elements is not preserved. So, when we iterate over `set_A` or `set_A`, the order can change. **Better Approach:** If we want to maintain the order of the elements in the original list $A$ or $B$, we can iterate over the original list directly rather than converting it to a set. Here's how:```{python}#| code-fold: false@time_requireddef intersection_of_two_sets(A, B): set_B =set(B) return [a for a in A if a in set_B]A = [2, 3, 5, 6, 8]B = [4, 6, 8]print(intersection_of_two_sets(A, B))```### 2. Max product of $k$ elements from an array of $n$ elements <p style="text-align:justify">Say we have an array of size $n$. We want to find the maximum of the products of $k$ elements from the array where $k < n$. For example, if we set $k=3$ and if we have $A=[1,2,3,4,5,6]$ then the answer is 120, if we have $B=[-3,-4,3,5]$ then the answer is 60.</p> **Solution**`nlargest` and `nsmallest` are two functions from the `heapq` library that returns $n$ largest and $n$ smallest numbers in decreasing and increasing order, respectively. For example,```{python}#| code-fold: falseimport heapqA = [1,2,3,4,5,6]B = [-3,-4,3,5]print('For set {}\n largest 3 numbers {}\n smallest 2 numbers'.format(A,heapq.nlargest(3,A)),heapq.nsmallest(2,A))print('\n')print('For set {}\n largest 3 numbers {}\n smallest 2 numbers'.format(B,heapq.nlargest(3,B)),heapq.nsmallest(2,B))```Now if all the elements are positive, then the maximum product of $k=3$ elements would just be the product of the largest three element. However, if the set contains negative numbers like the one in the example, product of the smallest two negative numbers and the first element from the `nlargest` element that would be the largest. ```{python}#| code-fold: falsek =3def max_of_three_element_product(arr): m = heapq.nlargest(k, arr) n = heapq.nsmallest(k-1, arr)returnmax(m[0]*m[1]*m[2], m[0]*n[0]*n[1])A = [1,2,3,4,5,6]B = [-3,-4,3,5]print('Max product of {} elements from set A={} is'.format(k,A), max_of_three_element_product(A))print('Max product of {} elements from set B={} is'.format(k,B), max_of_three_element_product(B))```### 3. Find the $k$ nearest points from a given point ```{python}#| code-fold: false@time_requireddef knearest(points: list[list[int]], k: int) ->list[list[int]]: dis = []for x in points: d =pow(pow(x[0],2)+pow(x[1],2),0.5) dis.append((x,d)) dis.sort(key=lambda item: item[1])return [x for x,_ in dis[:k]]pts = [[2,-1],[3,2],[4,1],[-1,-1],[-2,2]]k =3print(knearest(pts,k))```# [Internship and Full Time Job Preparation Review](/posts/jobandintern/index.qmd){style="text-decoration:none"}**Share on** <div id="fb-root"></div><script async defer crossorigin="anonymous" src="https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v20.0"></script><div class="share-buttons"><div class="fb-share-button" data-href="https://mrislambd.github.io/posts/dsa/"data-layout="button_count" data-size="small"><a target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fmrislambd.github.io%2Fposts%2Fdsa%2F&src=sdkpreparse" class="fb-xfbml-parse-ignore">Share</a></div><script src="https://platform.linkedin.com/in.js" type="text/javascript">lang: en_US</script><script type="IN/Share" data-url="https://mrislambd.github.io/posts/dsa/"></script> <a href="https://twitter.com/share?ref_src=twsrc%5Etfw" class="twitter-share-button" data-url="https://mrislambd.github.io/posts/dsa/" data-show-count="true">Tweet</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div><div class="fb-comments" data-href="https://mrislambd.github.io/posts/dsa/" data-width="" data-numposts="5"></div>**You may also like**