When I try to make the next attribute of a node, p, of a linked list point to None, I use p.next = None. But what if I want to make the node corresponding to p.next to None?
An example would be when try to rotate a linked list, which ends with a node's next equal to None, I want to make the new list's last element's next point to None but I think I keep deleting the element that it pointed to.
Here's my code for rotating the list by k positions. If you want to see the full description of the problem see here
def rotate(head, k):
'''
head is pointer to the head, k is the number of positions to rotate
'''
if not head or k == 0:
return head
p = head
d = head
counter = 1
while p.next != None:
counter += 1
p = p.next
out = ListNode(0)
if k % counter == 0:
return head
if counter < k:
counter = counter % k
for _ in range(counter):
p.next = d
d = d.next
p = p.next
out = p
d.next.next = None
return out
Sounds like you want to take the last k values and append them to the front.
p.next is the next node. In general when we want to change p's next we need to grab temp = p.next p.next = newNode and then we can continue.
In this case though, I'd find the length of the list, set tail.next = head, subtract k (accounting for wraparound), then walk forward till N-k, and set that node's p.next = None
Something like:
p, len, prev = head, 0, None
while p:
prev = p
p = p.next
len += 1
# prev is tail, set it's next to head
prev.next = head
# find the node to detach
p = head
for i in xrange(len):
p = p.next
p.next = None
You'll need to figure out corner cases
Related
Remove duplicates from an unsorted linked list
Given an unsorted linked list of N nodes. The task is to remove duplicate elements from this unsorted Linked List. When a value appears in multiple nodes, the node which appeared first should be kept, all others duplicates are to be removed.
Example 1:
Input:
N = 4
value[ ] = {5,2,2,4}
Output: 5 2 4
Example 2:
Input:
N = 5
value[] = {2,2,2,2,2}
Output: 2
My Code
def removeDuplicates(head):
if head is None or not head.next:
return head
d = {}
curr = head
prev = None
while curr.next:
prev = curr
curr = curr.next
if curr.data in d:
prev.next = curr.next
else:
d[curr.data] = 1
return head
In your while loop as condition you need curr instead of curr.next. And you need to overwrite curr at the end of the while loop. Like this:
def removeDuplicates(head):
if head is None or not head.next:
return head
d = {}
curr = head
prev = None
while curr:
if curr.data in d:
prev.next = curr.next
else:
d[curr.data] = 1
prev = curr
curr = curr.next
return head
I am trying to write code for a Linked List so that it deletes a node in the linked list, it can be any node except for the first and last nodes in the linked list. I have come up with some ideas below.
I'm not sure how to complete it, I know there needs to be some reference to k in the while loop, so that we skip over the node when traversing the linked list, but how can I reference this k? Would I do a 'for I in range k', and then on the kth iteration perform the skip?
def delete_middle(l1,k):
if l1.head is None:
return None
current = l1.head
while current:
if current == k:
current.next = current.next.next
current = current.next
return head
node.value = node.next.value
node.next = node.next.next
If you want to remove the kth node where k is an integer you can do this:
def delete_middle(l1,k):
if (l1.head is None) or (k == 0) or (k == find_length(l1) - 1): # second condition checks if k is the first value and the third condition checks if k is the last value which you didn't want to remove.
return None
n = 0 # index counter for the values in the linked list
head = l1.head
current = head
while current is not None:
if n + 1 == k: # check if the next node is the node that you want to remove
current.next = current.next.next
break
current = current.next
n += 1
return head
def find_length(l1): # to returns the length of the linked list
curr = l1.head
n = 0
while curr is not None:
curr = curr.next
n += 1
return n
Also, I'd recommend defining a linked list class with methods like these inside so you won't have to care about returning any value while updating the linked list unless an invalid value is sent.
Given a singly linked list, i am trying to reverse k nodes at a time through out the list.
So, if k = 2, 1 -> 2 -> 3 -> 4 -> 5 -> 6 will turn into 2 -> 1 -> 4 -> 3 -> 6 -> 5. It is assumed that k is always a factor of the length of the list (Length of the list is divisible by k).
I am trying to solve this using an iterative approach rather than a recursive one. I am trying to parse the list as sets of k nodes and reverse them each till the end of the list. This is my code
def reverseList(A, B): # param A : head node of linked list, param B : integer, return the head node in the list
if B < 2:
return A
dummy = ListNode('dummy')
dummy.next = A
prev, behind = dummy, A
while behind:
ahead = behind
for i in range(B-1):
ahead = ahead.next
new_behind = reverse_list(behind, ahead)
prev.next = ahead
behind.next = new_behind
behind = behind.next
return dummy.next
The reverse_list function reverses the list from the start to end nodes of a k set and returns the node at the beginning of the new k set of nodes (the new start node)
def reverse_list(start, end):
prev, curr = None, start
while prev is not end:
next = curr.next
curr.next = prev
prev = curr
curr = next
return curr
The definition of ListNode class
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
When the values A = [ 6 -> 10 -> 0 -> 3 -> 4 -> 8 ] and B = 3 are given, the output is 8 -> 4 -> 3. What exactly am I missing or overlooking? Any help is greatly appreciated.
For each iteration, you should point the next node of the current node to the next node of the next node, then point the next node of the next node to the head node, and then point the head node to the next node, to complete a reversal of the give number of nodes. Then assign the current node as the new head, repeat the above, until the next node of the head is None:
def reverseList(A, B):
head = A
while head.next:
node = head.next
for _ in range(B - 1):
next_node = node.next
if next_node:
node.next = next_node.next
next_node.next = head.next
head.next = next_node
head = node
return A
Demo: https://repl.it/#blhsing/ElatedSurefootedFilesize
I've figured out the mistake i've been making. I didn't update the 'prev' pointer while updating the 'behind' pointer. It should have been
prev = behind
After getting the behind and ahead pointers, this should be the block of code within the while loop in reverseList function
new_behind = reverse_list(behind, ahead)
prev.next = ahead
behind.next = new_behind
prev = behind
behind = behind.next
I am trying to count the numbers of nodes in a linked list when the node value is a non-negative odd, but it seems that I couldn't get the right result.
class Solution:
"""
#param head:
#return: nothing
"""
def countNodesII(self, head):
count = 0
while head.next is not None:
head = head.next
if head.val > 0 and head.val % 2 != 0:
count += 1
else:
return 0
return count
if the input is 1->3->5->null
I expect to get result of 3, but my program returned 2 instead.
Some issues in your code
You would want to move to next node via head=head.next after you check the head node for the condition, right now you are skipping head
You would want to remove return from else, and only return count at the end
You want to check if head reaches None since you are using it to iterate over your list
So the updated code will look like
class Solution:
"""
#param head:
#return: nothing
"""
def countNodesII(self, head):
count = 0
#Iterate over the list
while head != None:
#Check for condition
if head.val > 0 and head.val % 2 != 0:
count += 1
#Move to next node
head = head.next
return count
I have the code below that merges two sorted linked lists in python.
what I can't understand is that at what point it adds the value of the second list to the first list.
I would be grateful if somebody could explain this to me.
def merge_sorted(self, llist):
# set p and q pointers to head nodes of list1 and list2 (both of p,q are objects of class Node)
p = self.head
q = llist.head
s = None
# if either of the two lists doesn't exist return out of function (no point of sorting)
if not p:
return
if not q:
return
# if both head pointers exist:
if p and q:
#based on which header data being smaller set s to that one
if p.data <= q.data:
s = p
p = s.next # move p to next element, can also write : p = p.next
else:
s = q
q = s.next # move p to next element, can also write : q = q.next
new_head = s
# go through all elements of both lists (after p/q being updated)
while p and q:
if p.data <= q.data:
# the p/q here is one item iterated ahead of when we set s = p/q
s.next = p
# then we move s one item ahead, it its next pointer
s = p # could also write s = s.next
p = s.next # could also write p.next, we move p one item ahead
else:
s.next = q
s = q # could also write s = s.next
q = s.next # could also write p.next, we move p one item ahead
# when you reach the end of the list in one of the lists, set s to whatever is left of the other list and finish merging
if not p:
s.next = q
if not q:
s.next = p
self.head = new_head