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.
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
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
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
I am trying to figure out how to print the lowest k values in a binary search tree. I an having trouble stopping the method
code:
def kthSmallestBST(node,k, count):
if node == None or count == k:
return
else:
kthSmallestBST(node.left, k, count)
count += 1
print node.data
kthSmallestBST(node.right, k, count)
count += 1
kthSmallestBST(BST, 3, 0)
Currently my output simply printed the whole tree inorder
It's a rather "functional programming" solution, but one way is to generate (lazily) the nodes in the tree in order, and then using itertools to just take the first k.
def inorder(tree):
if not tree: return
for node in inorder(tree.left): yield node
yield tree
for node in inorder(tree.right): yield node
def least(tree, k):
return itertools.islice(inorder(tree), k)
If you're using Python 3, you can use "yield from" to make this solution shorter.
Changes to the value of count don't propagate back up to the caller. You need to return the new count:
def kthSmallestBST(node,k, count):
if node is None or count >= k:
return 0
else:
count += kthSmallestBST(node.left, k, count)
if count < k:
print node.data
count += 1
count += kthSmallestBST(node.right, k, count)
return count
Also note you don't need both k and count. You can get rid of count, decrement k instead of incrementing count, and compare k against 0 (instead of against count). Here's what you get:
def kthSmallestBST(node, k):
if node is None or k <= 0:
return 0
k = kthSmallestBST(node.left, k)
if k > 0:
print node.data
k -= 1
k = kthSmallestBST(node.right, k)
return k
You need to change things around a bit so you know how many elements were found during the recursive call. Have the function return the number of elements it found an add them up. Also you need to check the count between the recursive calls and the current node's element.
Something like:
def kthSmallestBST(node, k, count):
if node == None or count == k:
return 0
else:
count += kthSmallestBST(node.left, k, count)
if(count == k)
return count
print node.data
count += 1
count += kthSmallestBST(node.right, k, count)
return count
import unittest
class BST(object):
def __init__(self, key):
self.key = key
self.left = None
self.right = None
def get_kth_smallest_keys(node, k):
"""Return, as a list, `k` smallest keys in a binary search tree rooted at `node`.
"""
smallest = []
_get_kth_smallest_keys(node, k, smallest)
return smallest
def _get_kth_smallest_keys(node, k, smallest):
"""A helper function. Appends nodes to the given list, `smallest`, and stop
when k reaches 0.
Returns the number of nodes appended to said list.
"""
if node is None or k == 0:
return 0
# first, recurse left, and we get the number of nodes appended to the list by that call
nk = _get_kth_smallest_keys(node.left, k, smallest)
# if that number already reduces our counter to zero, we fail fast, returning that same number
if k - nk <= 0:
return nk
# otherwise, we can still append this node's key to the list
smallest.append(node.key)
# then we recurse right, with a counter that is less 1 (our append) and less nk (appended by the left recurse)
nnk = _get_kth_smallest_keys(node.right, k - 1 - nk, smallest)
# our return value is the sum of our append (1) and the appends from both recurse calls
return nk + 1 + nnk
class BSTTest(unittest.TestCase):
def test_smallest_keys(self):
root = BST(10)
root.left = BST(6)
root.right = BST(15)
root.left.right = BST(8)
root.right.right = BST(20)
self.assertEquals(get_kth_smallest_keys(root, 0), [])
self.assertEquals(get_kth_smallest_keys(root, 1), [6])
self.assertEquals(get_kth_smallest_keys(root, 3), [6, 8, 10])
self.assertEquals(get_kth_smallest_keys(root, 5), [6, 8, 10, 15, 20])
self.assertEquals(get_kth_smallest_keys(root, 6), [6, 8, 10, 15, 20])
if __name__ == '__main__':
unittest.main()