python rename variables in vsc_Python关于变量赋值和函数参数传递(3)——VC++,python,与,三,VSC...

例题:

给定两个

非空

链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储单个数字。将这两数相加会返回一个新的链表。

你可以假设除了数字 0 之外,这两个数字都不会以零开头。

进阶:

如果输入链表不能修改该如何处理?换句话说,你不能对列表中的节点进行翻转。

示例:

输入: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)

输出: 7 -> 8 -> 0 -> 7

1. 使用C++引用传递,函数调用过程中修改的都是同一个地址空间中保存到carry值(进位值)

class Solution {

public:

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {

int len1 = get_length(l1), len2 = get_length(l2);

int len = max(len1, len2);

if(len1 != len2){

ListNode* head = len1 < len2 ? l1 : l2;

for(int i = 0; i < len - min(len1, len2); i ++){

ListNode* node = new ListNode(0);

node->next = head;

head = node;

}

if(len1 < len2) l1 = head;

else l2 = head;

}

int carry = 0;

ListNode* res = go(l1, l2, carry);

if(carry){

ListNode* node = new ListNode(1);

node->next = res;

res = node;

}

return res;

}

private:

int get_length(ListNode* head){

if(!head) return 0;

return 1 + get_length(head->next);

}

ListNode* go(ListNode* l1, ListNode* l2, int& carry){ //使用引用传递

if(!l1){

assert(!l2);

carry = 0;

return NULL;

}

ListNode* next = go(l1->next, l2->next, carry); //递归调用,carry 使用引用传递

int x = l1->val + l2->val + carry; //递归调用过程中使用的都是同一个地方的carry值

ListNode* res = new ListNode(x % 10);

res->next = next;

carry = x / 10;//递归调用过程中修改的都是同一个地方的carry值

return res;

}

};

2. 在python中跟上面C++一样的写法就是错的

错误的代码:

def addTwoNumbers2(l1: ListNode, l2: ListNode) -> ListNode:

def get_len(head):

if not head:

return 0

return 1 + get_len(head.next)

def add(l1,l2,carry):

if not l1:

carry = 0

return None

next = add(l1.next, l2.next,carry) ## !!!!

sum = l1.val + l2.val + carry ## !!!! 无法获取在下一层调用中更新的carry值,这里的这一层函数中的carry值仍然是0

node = ListNode(sum%10)

node.next = next

carry = sum // 10 ## !!!!

return node

len1, len2 = get_len(l1), get_len(l2)

len = max(len1,len2)

head = l1 if len1 < len2 else l2

for i in range(len - min(len1,len2)):

node = ListNode(0)

node.next = head

head = node

if len1 < len2:

l1 = head

else:

l2 = head

carry = 0

res = add(l1,l2,carry)

if carry:

node = ListNode(carry)

node.next = res

res = node

return res

错误的原因:

因为python中每次递归函数调用传递的都是不可变对象(进位值,是一个数值常量),当在函数中 更新carry = x // 10 时,只是该函数内部空间的局部变量(标签)carry又绑定到了另一个不可变对象 x // 10上了,该函数返回到上一级函数中,上一级函数内部空间的局部变量(标签)carry仍然绑定在原来绑定的不可变对象0上,也就是说在python中,这种函数参数传递方式在递归调用中无法获取下一层中的carry更新值

正确的代码:

递归函数返回本层函数调用更新后的carry值

class Solution:

def addTwoNumbers(self, l1, l2):

def add(num1, num2, i, j):

if not i or not j:

return 0

if num1 > num2:

temp = i.val + add(num1 - 1, num2, i.next, j)

else:

temp = i.val + j.val + add(num1, num2, i.next, j.next)

i.val = temp % 10

return temp // 10 # 递归函数返回本层函数调用更新后的carry值

num1 = num2 = 0

cur = l2

while cur:

num2 += 1

cur = cur.next

cur = l1

while cur:

num1 += 1

cur = cur.next

if num2 > num1:

l1, l2 = l2, l1

num2, num1 = num1, num2

if add(num1,num2,l1, l2):

l2 = ListNode(1)

l2.next = l1

l1 = l2

return l1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值