Below is a code that divides each number of the node by 10. For example, node = 2->3->3, output would be 0.2->0.3->0.3.
However I am confused on why self.head.next gets updated each time given it's cur that receive the change. Suppose a=1,b=2 and we make a(cur)=b(self.head), if we change the value of a to 3, that wouldn't affect b, b is still 2. Therefore I couldn't understand why changing cur would affect self.head.next. Thank you!
class node(object):
def __init__(self,value,next=None):
self.value=value
self.next=next
class linkedlist(object):
def __init__(self):
self.head=None
self.next=None
def test(self,List):
self.head=node(0)
cur=self.head
while List:
s=List.value/10
cur.next=node(s)
cur=cur.next
List=List.next if List else 0
return self.head.next
Suppose below is the input:
a=node(2)
a=node(2,a)
a=node(3,a)
c=linkedlist()
Below is the output:
c.test(a).value=0.3
c.test(a).next.value=0.2
c.test(a).next.next.value=0.2
I am confused on why self.head.next gets updated each time given it's cur that receive the change
That is because, at least in the first iteration of the loop, self.head is cur:
cur=self.head
After that, it builds a new list with updated values, using a "dummy" node as self.head (and thus the first cur) which is then discarded and only it's next is returned. However, I find that code rather confusing and overly complicated (I had a hard time understanding it myself), e.g. the ternary ... if ... else ... in the last line is redundant as List can not be None at that point. Also, there's no need in making that a class, since none of its member attributes are used beyond the scope of a single execution of the method.
Instead, you could use a simple function, e.g. using a loop and modifying the original list, or even simpler, recursively creating a new list:
def div(lst, d=10):
first = lst
while lst:
lst.value /= d
lst = lst.next
return first
def div(lst, d=10):
return node(lst.value / 10, div(lst.next, d)) if lst else None
For easier debugging, you can also add a __repr__ method to your node class:
def __repr__(self):
return "(%r %r)" % (self.value, self.next)
Related
I'm new to programming, so excuse the possibly stupid question.
I'm doing leetcodes and I got to the linked lists. I think I understand them okay, it's just that I don't know how to test my code/call my function(?)
Problem I'm working on
Here's my code, I know it works since I uploaded it onto leetcode, but I would still like to be able to run it on my machine.
class Solution:
def middleNode(self, head: Optional[ListNode]) -> Optional[ListNode]:
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
return slow
I guess I have two different problems:
the "Optional[ListNode]) -> Optional[ListNode]:" part
and the actual calling of the function
Some questions before used the "typing" module functions like "List", so I would simply import them and they wouldn't be a problem. But I'm not really sure what to do here
To check my solutions, I write a short piece of code that I can put example inputs into
Solution = Solution()
print(Solution.middleNode(head = [1,2,3,4,5,6]))
But isn't the "head" there, just a normal list? Do I have to create an extra function separately to create the "links". I've seen the creation of a linked list done by calling a function every time you want to add a new node. So would I use a for loop to add my example case?
well if you looking for internal boilerplate, below is code for that.
here you need to create classes for nodes, linked list and solutions,.
then with the given number, you need to create a linkedlist object.
this above part is done in leetcode by themself and this object is passed to class Solution method middleNode, where OP code run and give result. next once output is got it is compared with existing solution
# Node class for individual nodes
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
# linked list class, to create a linked list of the list nodes
class LinkedList:
def __init__(self):
self.head = None
# adding a node element to linked list
def add(self, node):
if self.head is None:
self.head = node
else:
curr = self.head
while curr.next:
curr = curr.next
curr.next = node
curr = node
# printing element of existing linked list
def print_ll(self):
curr= self.head
while curr:
print(curr.val)
curr= curr.next
# leetcode solution class
class Solution:
def middleNode(self, head) :
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
return slow
# value with which we create list nodes
values = [1,2,3,4,5,6,7,8,9,10]
ll = LinkedList() # create a linked list class object
for i in values:
node = ListNode(i) # creating a list node
ll.add(node) # adding list node to linked list
#ll.print_ll() # printing linked list
x = Solution().middleNode(ll.head) # passing linked list object to leetcode solution method and getting result
while x: # printing result
print(x.val)
x=x.next
I think the problem on LeetCode is poorly worded. head = [1,2,3,4,5] is not really a head as it should only refer to the first item in the list - there seems to be a bit of hidden boilerplate code that creates a linked list from input list and an output list from output node.
Here's an example code that works similiar to the LeetCode task.
from typing import Optional
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def middleNode(self, head: Optional[ListNode]) -> Optional[ListNode]:
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
return slow
inp = [1,2,3,4,5,6]
next = None
for i in reversed(inp):
next = ListNode(i, next) # next points to head at the end of the loop
res = Solution().middleNode(next)
out = []
while res:
out.append(res)
res = res.next
print([o.val for o in out])
to make your code work on your machine you have to implement a couple of things:
First, for your first answer, you have to implement the class ListNode given at the top of the leetcode-page:
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
The you import "Optional" from typing:
from typing import Optional
Then you have the prerequisites for your code.
You have to initialise the class, as you have mentioned. The only problem here is, that your variable has the same name as your class, what could cause trouble later.
To finish, you have to call your function as you already did, with one little difference: This function has to be called with "head" as a variable of type ListNode, not List, and gives you back a variable of the type ListNode.
In a nutshell, this would be my solution (of course you can and as much ListNodes as you want):
from typing import Optional
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def middleNode(self, head: Optional[ListNode]) -> Optional[ListNode]:
slow = fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
return slow
# Initialise class
s = Solution()
# Defining nodes of the list, assigning always the next node.
seven = ListNode(7)
six = ListNode(6, next=seven)
five = ListNode(5, next=six)
four = ListNode(4, next=five)
three = ListNode(3, next=four)
two = ListNode(2, next=three)
one = ListNode(1, next=two)
# Calling your function (with "one" as your head node of the list)
# NOTE: As this gives you back an attribute of type ListNode, you have to access the "val" attribute of it to print out the value.
print(s.middleNode(one).val)
I'm new to the concept of recursion, had never practiced this magic in my coding experience. Something I'm really confused about Python recursion is the use of "return". To be more specific, I don't quite understand when to use return in some situations. I've seen cases where the return is used before recursion, and cases return is not needed at all.
For example:
A Leetcode Question: "Given the root node of a binary search tree (BST) and a value. You need to find the node in the BST that the node's value equals the given value. Return the subtree rooted with that node. If such node doesn't exist, you should return NULL."
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def searchBST(self, root, val):
"""
:type root: TreeNode
:type val: int
:rtype: TreeNode
"""
if root == None:
return root
if root.val == val:
return root
elif root.val > val:
return self.searchBST(root.left,val)
else:
return self.searchBST(root.right,val)
Why do I need to return "self.searchBST(root.left,val)" and "self.searchBST(root.right,val)"? If there is no return added for the two lines, would't the program still run recursively until the conditions of root.val == val or root== None is met, and a value is returned? (I know it's not the case in practice, I'm just trying to conceptualize it).
Moreover, could someone kindly show me the general guideline for using return in recursions? Thank you in advance!
If you just write:
self.searchBST(root.left,val)
instead of
return self.searchBST(root.left,val)
it will perform the recursive search but won't return the result back to the block in which it is invoked. When it gets to the value you want (or doesn't find it), that call will do
return root
But the previous call will just discard this value, rather than returning it back up the recursion chain.
A return statement exits the currently running function and returns a return value, which can then be used like any other value in Python: assigned to a variable, passed as the argument to another function, or ... returned as the return value of the calling function.
def some_func():
return 'result'
x = some_func() # after this, x == 'result'
If you call a function without capturing the return value, it just gets lost. So, if you just call some_func(), it will get executed.
some_func() # this works, but 'result' is lost
The same goes for a function that calls another function, even if that other function is itself:
def some_other_func1():
x = some_func()
return x
def some_other_func2():
return some_func() # exact same result as some_other_func1()
def some_recursive_func(n):
if n == 0:
print('Reached the end')
return n
else:
print(f'At {n}, going down')
return some_recursive_func(n-1)
print(some_recursive_func(3)) # prints a bunch of lines, but always prints `0` at the end
Let's take an even simpler example and you can apply the same logic to your method as well,
def fact(n):
#Base case
if n in [0, 1]:
return 1
#Recursion. Eg: when n is 2, this would eventually become 2 * 1 and would be returning 2 to the caller
return n * fact(n-1)
In general a recursive function will have 2 cases, one being the base case and the other being recursive call to self. And remember, this is a function and ideally is supposed to return something to the caller. That is where return statement would be needed. Otherwise you wouldn't be returning right value to the caller.
If there is no return added for the two lines, would't the program still run recursively until the conditions of root.val == val or root== None is met, and a value is returned
Value is returned yes. But it would be returned to previous call (and so on) and hence it would return to one of self.searchBST(root.left,val) or self.searchBST(root.right,val). You would still need to return from this point to the caller of the function. Hence you would need to have return self.searchBST(root.left,val) or return self.searchBST(root.right,val).
I am often compiling lists one element at a time in python 3; say for instance I am making a list by going through a linked list with first element head:
l = []
while head:
l.append(head.val)
head = head.next
I was wondering what the best practices are. Is there another way of writing this? Could it be possible to describe the list in one line, with something like this instead:
while head:
l = # something creating the list AND appending elements
head = head.next
Even better: do I always have to use a loop to create lists in similar cases, or are there often ways to make the desired list in one line ?
Thanks!
EDIT : a typo in the code !
From an OOP perspective, the best practice is to rely on Python's __iter__ method to cast an iterable to a list.
I am assuming your linked-list class looks a bit like this.
class LinkedList:
def __init__(self, value, nxt=None):
self.value = value
self.next = nxt
To allow iteration on your linked-list, you can define __iter__
class LinkedList:
def __init__(self, value, nxt=None):
self.value = value
self.next = nxt
def __iter__(self):
while self:
yield self.value
self = self.next
You can then let list handle the cast of the LinkedList iterable.
head = LinkedList(1, LinkedList(2, LinkedList(3)))
lst = list(head) # [1, 2, 3]
There are two solution for a problem:
Problem is :
Enter the root node of a binary tree and an integer to print out the path where the sum of the node values in the binary tree is the input integer. A path is defined as a path from the root node of the tree to the next node until the leaf node passes. (Note: In the list of return values, the array with the largest array length is ahead)
solution one
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def FindPath(self, root, expectNumber):
if not root:
return []
result=[]
path=[root]
path_sum=0
def find(root,path,path_sum):
isleaf= root.left==None and root.right==None # a bool,whether is leaf node
path_sum+=root.val
if isleaf and path_sum==expectNumber:
t=[]
for i in path:
t.append(i.val)
result.append(t) # add a appropriate path's value to result
if path_sum<expectNumber:
if root.left:
find(root.left,path+[root.left],path_sum)#note!!!!!
if root.right:
find(root.right,path+[root.right],path_sum)#note!!!!!
find(root,path,path_sum)
return result
solution 2
class Solution:
def FindPath(self, root, expectNumber):
if not root:
return []
result=[]
path=[]
path_sum=0
def find(root,path,path_sum):
isleaf= root.left==None and root.right==None
path.append(root)#note!!!!!
path_sum+=root.val
if isleaf and path_sum==expectNumber:
t=[]
for i in path:
t.append(i.val)
result.append(t)
if path_sum<expectNumber:
if root.left:
find(root.left,path,path_sum)
if root.right:
find(root.right,path,path_sum)
path.pop()#note!!!!!
find(root,path,path_sum)
return result
I don't know why in solution 1 the path list don't need pop operation but solution 2 need. In other word why solution 1 don't share a path list, but solution 2 does.
Please help me, I cann't find such paper figure me out!
My point is not about class , you can use function to solve this problem too.
What I care is Python variable value assignment in recursion!!!
I find your code has a lot of mistakes that will make it hard to trace:
**** First: any def or function inside any Python class should be lower case with underscores, so we can figure out what is class from a function, so your FindPath() should be >>>>>> find_path()
**** Second: If you wand to declare any arguments to a the global scope of a class, you should do that inside a function as a constructor or initializer, so your code for an E.G should be :
class Solution:
def __init__(self, root, expect_number):
self.root = root
self.expect_number = expect_number
and any time you will call any argument inside the class, you should call it with the (self.arg), e.g self.root
**** Third: this line is not understandable at all :
def find(root,path,path_sum):
isleaf= root.left==None and root.right==None
this is totally wrong you are assigning a None value to preassaigned value to isleaf, and you again give the isleaf variable an (and) word so, as a logical or pythonic logic : how would the isleaf will understand to get the two values (root.left and root.right) which are getting a None values, does not make any sense.
so please give us an idea about what exactly do you want to do here.
**** Fourth: consider to give one space after and before any operator so instead of
"if path_sum
**** Don't afraid to give the variables or arguments a real names to discripe the real needs for it, or at least try to give a comment for it, So e.g : what is t = [] is doing!!!!!!!
So please try to be more specific so you can find good help for your problems, and to make your code more pythonic.
New Edit:
In solution no 2 : every time you call the find() function, you are appending or adding the 'root' value to the path list
def find(root,path,path_sum):
isleaf= root.left==None and root.right==None
path.append(root) # here you added the root to the path
and the code still recursive till this condition is false:
if path_sum<expectNumber:
and when it false, it will start to call the pop() method, which will remove
the last 'root', added to the path list:
path.pop()
and then it calls the next line, which will call the find function again
find(root,path,path_sum)
but this time will call it with empty path value, WHY?
because the first path list object "path=[]" is at the same level scope as
the calling of the last find function "find(root,path,path_sum)"
so the inner path argument and it's values not seen by the outer path scope, they only seen by the find() function it self.
And this scope issues exactly the same to "Solution 1", except you are passing a path list with root value, and when this condition is False
if path_sum<expectNumber:
the code will call the find() function again but with path only having the root value in the first announcement "path=[root]".
And After all I think with respect you are not sharing the whole code for privacy issue, so it's hard to find the answer easily.
You can simplify your recursive method several ways. First, at each iteration, check if the value of the node passed to the method along with the sum of the current path contents is less than or equal to the desired value. Second, should the latter be smaller, call the method on the left and right sides of the tree:
class Solution:
#classmethod
def find_path(cls, head, val:int, current = []):
if sum(current) == val:
yield current
elif head.value+sum(current) < val:
if head.left is not None:
yield from cls.find_path(head.left, val, current+[head.value])
if head.right is not None:
yield from cls.find_path(head.right, val, current+[head.value])
elif head.value+sum(current) == val:
yield current+[head.value]
Tree class for demonstration:
class Tree:
def __init__(self, **kwargs):
self.__dict__ = {i:kwargs.get(i) for i in ['left', 'right', 'value']}
t = Tree(value=10, left=Tree(value=8, left=Tree(value=3), right=Tree(value=5)), right=Tree(value=2, left=Tree(value=2)))
"""
10
/ \
8 2
/ \ /
3 5 2
"""
results = [list(Solution.find_path(t, i)) for i in [12, 14, 23]]
Output:
[[[10, 2]], [[10, 2, 2]], [[10, 8, 5]]]
I've tried to write a function that takes three parameters: a linked list, a value, and a new value. The purpose of the function is to add the new value after the value in the linked list. Here's my function.
def addAfter(lis, value, newValue):
tracker = lis
while tracker != None:
if tracker['data'] == value:
newNode = {'data':newValue, 'next': tracker['next']}
tracker['next'] = newNode
break
else:
tracker = tracker['next']
For some reason I can't get this function to do anything. It doesn't change the list. I was wondering if someone could tell me what I'm doing wrong.
The problem is probably in how you're defining your initial nodes or list. For example, the following code works in Python3.4
def addAfter(lis, value, newValue):
tracker = lis
while tracker != None:
if tracker['data'] == value:
newNode = {'data':newValue, 'next': tracker['next']}
tracker['next'] = newNode
break
else:
tracker = tracker['next']
node1 = {'data':3,'next':None}
addAfter(node1,3,4)
print(node1)
print(node1['next'])
This outputs
{'next': {'next': None, 'data': 4}, 'data': 3}
{'next': None, 'data': 4}
As we'd expect it to. So there are several possibilities here
You're not using dictionaries at all - you defined a custom class and overloaded the setitem and getitem. I highly doubt this
You overloaded equals or hash so that the evaluations aren't correct. Doubt this too
You're using non-built-in objects as values and didn't overload the equals, so when you compare Foo() to Foo() it evaluates false. This seems somewhat likely. You might think that things are equal, when in fact Python is checking if they lie at the same memory location, not that their fields match
Your test code is wrong, you're printing out a copy of the data not the original data. This sort of thing is always a possibility
Try testing for each of those and let us know if none pan out. If not, provide a little more context, i.e., a scenario where the break is evident
Could you add a new class such as :
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
and then use the code of en_Knight, otherwise, the code will be hard to read