Skip to content

Commit ee75f9a

Browse files
committed
LinkedList related problems added
1 parent ce866a7 commit ee75f9a

File tree

4 files changed

+262
-0
lines changed

4 files changed

+262
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
'''
2+
Question: https://leetcode.com/problems/linked-list-cycle/
3+
4+
Given head, the head of a linked list, determine if the linked list has a cycle in it.
5+
There is a cycle in a linked list if there is some node in the list that can be reached
6+
again by continuously following the next pointer. Internally, pos is used to denote the
7+
index of the node that tail's next pointer is connected to. Note that pos is not passed
8+
as a parameter.
9+
Return true if there is a cycle in the linked list. Otherwise, return false.
10+
11+
=> => =>
12+
Input: head = [3,2,0,-4], pos = 1
13+
Output: true
14+
Explanation: There is a cycle in the linked list, where the tail connects to
15+
the 1st node (0-indexed).
16+
17+
Input: head = [1,2], pos = 0
18+
Output: true
19+
Explanation: There is a cycle in the linked list, where the tail connects to the 0th node.
20+
21+
22+
Follow up: Can you solve it using O(1) (i.e. constant) memory?
23+
24+
25+
'''
26+
27+
# Time: O(n); Space: O(1)
28+
# Definition for singly-linked list.
29+
class ListNode:
30+
def __init__(self, x):
31+
self.val = x
32+
self.next = None
33+
34+
class Solution:
35+
def hasCycle(self, head: Optional[ListNode]) -> bool:
36+
# Idea : Place some new unique value to current node value
37+
# if that value again comes then it has cycle
38+
# Time: O(n); Space: O(1)
39+
temp = head
40+
while temp:
41+
if temp.val == float('-inf'):
42+
return True
43+
44+
temp.val = float('-inf')
45+
temp = temp.next
46+
return False
47+
48+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
'''
2+
Question: https://leetcode.com/problems/merge-two-sorted-lists/
3+
You are given the heads of two sorted linked lists list1 and list2.
4+
Merge the two lists in a one sorted list. The list should be made by splicing together the nodes of the first two lists.
5+
Return the head of the merged linked list.
6+
=> => => => =>
7+
Input: list1 = [1,2,4], list2 = [1,3,4]
8+
Output: [1,1,2,3,4,4]
9+
Input: list1 = [], list2 = []
10+
Output: []
11+
12+
Idea Explained at: https://leetcode.com/problems/merge-two-sorted-lists/discuss/2253040/O(n)-O(1)Python-Merging-Explained-with-detail-output
13+
14+
'''
15+
# Solution: Time: O(n); Space: O(1)
16+
# Definition for singly-linked list.
17+
# class ListNode:
18+
# def __init__(self, val=0, next=None):
19+
# self.val = val
20+
# self.next = next
21+
class Solution:
22+
def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
23+
24+
dummy=ListNode()
25+
head = dummy
26+
# Take out all the values of both linked list
27+
while list1 and list2:
28+
if list1.val < list2.val:
29+
head.next = list1
30+
list1 = list1.next
31+
else:
32+
head.next = list2
33+
list2 = list2.next
34+
head = head.next
35+
# print(f"head: {head}")
36+
# print(f"Dummy: {dummy}")
37+
if list1 or list2:
38+
head.next = list1 if list1 else list2
39+
40+
# print("Finally")
41+
# print(f"head: {head}")
42+
# print(f"Dummy: {dummy}")
43+
return dummy.next
44+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
'''
2+
Question: https://leetcode.com/problems/reverse-linked-list/
3+
Given the head of a singly linked list, reverse the list, and return the reversed list.
4+
5+
=> => => =>
6+
Input: head = [1,2,3,4,5]
7+
Output: [5,4,3,2,1]
8+
9+
Input: head = [1,2]
10+
Output: [2,1]
11+
12+
Input: head = []
13+
Output: []
14+
15+
Follow up: A linked list can be reversed either iteratively or recursively. Could you implement both?
16+
17+
18+
'''
19+
# Definition for singly-linked list.
20+
class ListNode:
21+
def __init__(self, val=0, next=None):
22+
self.val = val
23+
self.next = next
24+
25+
# Appraoch 1: Iterative approach -> Time: O(n); Space: O(n)
26+
class Solution:
27+
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
28+
# Iterative solution
29+
# Time: O(n), Space: O(n)
30+
31+
if not head:
32+
return head
33+
34+
if not head.next:
35+
return head
36+
# Get the values of linked List
37+
values = []
38+
while head:
39+
values.append(head.val)
40+
head = head.next
41+
42+
# Create the new linkedlist with the values
43+
# Where the values are in reverse order
44+
for i in range(len(values)):
45+
if i == 0:
46+
left = ListNode(values[i])
47+
else:
48+
left = ListNode(values[i], left)
49+
# print(f"{left}")
50+
return left
51+
52+
53+
# Approach : Recursive with Queue Data Structure -> Time: O(n); Space: O(n)
54+
class Solution:
55+
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
56+
# Recursive Solution : Queue Data Structure
57+
# Time: O(n); Space: O(n)
58+
queue = []
59+
60+
self.process(head, queue)
61+
62+
return head
63+
64+
def process(self, head: Optional[ListNode], queue) -> None:
65+
66+
if not head:
67+
return
68+
queue.append(head.val)
69+
self.process(head.next, queue)
70+
# after recursive all the values are in queue
71+
# These values are in descending order
72+
# Just update head value with values of queue
73+
head.val = queue.pop(0)
74+
75+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
'''
2+
Question: https://leetcode.com/problems/palindrome-linked-list/
3+
Given the head of a singly linked list, return true if it is a palindrome.
4+
5+
=> => => =>
6+
Input: head = [1,2,2,1]
7+
Output: true
8+
9+
Input: head = [1,2]
10+
Output: false
11+
12+
Follow up: Could you do it in O(n) time and O(1) space?
13+
14+
'''
15+
16+
# Definition for singly-linked list.
17+
class ListNode:
18+
def __init__(self, val=0, next=None):
19+
self.val = val
20+
self.next = next
21+
22+
# Solution: Time: O(n); Space: O(n)
23+
# First we get all the values of LinkedList
24+
# Check whether that values is equal to reverse of this
25+
class Solution:
26+
def isPalindrome(self, head: Optional[ListNode]) -> bool:
27+
if head.next == None:
28+
return True
29+
values = []
30+
while head:
31+
values.append(head.val)
32+
head = head.next
33+
34+
# print(values)
35+
# Check if the values == reverse of that
36+
i = 0
37+
j = len(values) - 1
38+
while i < j:
39+
if values[i] != values[j]:
40+
return False
41+
i += 1
42+
j -= 1
43+
return True
44+
45+
46+
"Follow up: Could you do it in O(n) time and O(1) space?"
47+
# Solution : Time: O(n); Space: O(1)
48+
# We will utilize two algorithm methods:
49+
# Floyd's Tortoise & Hare Algorithm aka Fast and Slow Pointers + Linked List Reversal
50+
# Time is O(n) because in the worst case we are just traversing through the entire linked list in a single iteration time.
51+
# Space is O(1) because we aren't saving the entire input/linked list anywhere during our algorithm, so there is no scaling memory.
52+
# Only we keep track of variables and pointers.
53+
class Solution:
54+
def isPalindrome(self, head: Optional[ListNode]) -> bool:
55+
if head.next == None:
56+
return True
57+
58+
slow = head
59+
fast = head
60+
61+
# We use slow and fast pointer algorithm to get the middle of the linked list
62+
while fast and fast.next:
63+
slow = slow.next
64+
fast = fast.next.next
65+
66+
# reverse the second half head ; Reverse in between [slow, tail]
67+
secondHalfEnd = self.reverse(slow)
68+
69+
# check the reverse second half and first half
70+
# so use two pointers
71+
# Pointer1 is in starting and pointer2 is in middle
72+
pointer1 = head
73+
pointer2 = secondHalfEnd
74+
validPalindrome = True
75+
76+
while pointer1 and pointer2:
77+
if pointer1.val != pointer2.val:
78+
validPalindrome = False
79+
break
80+
pointer1 = pointer1.next
81+
pointer2 = pointer2.next
82+
83+
# Reverse the second half of the linked list back to normal
84+
self.reverse(secondHalfEnd)
85+
return validPalindrome
86+
87+
def reverse(self, head):
88+
prev = None
89+
current = head
90+
while current:
91+
temp = current.next
92+
current.next = prev
93+
prev = current
94+
current = temp
95+
return prev

0 commit comments

Comments
 (0)