2个非空链表相加

2个非空链表相加,里面的元素都是int类型,

比如  (3->4->1) + (1->2) ,返回4->6->1. 第一位是最低位

面试官想要的思路,在链表中挨个处理单个元素,需要注意进位的情况. 考察下链表的熟练程度和特殊情况的处理.

// 在链表中处理,挨个处理每个元素,需注意进位,和最后一位进位的情况,
// 效率上略高,O(最长的链表)但是读起来没有第一种好理解
class Solution {
    
    func addTwoNumbers(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
        
        guard l1 != nil else {
            return l2
        }
        guard l2 != nil else {
            return l1
        }
        // 占位节点,方便书写代码
        let result = ListNode.init(0)
        var workNode = result
        var overFlow = 0 // 是否有进位标志
        
        var first = l1
        var second = l2
        
        while first != nil || second != nil || overFlow != 0 {
            
            var firstVal = 0
            if first != nil {
                firstVal = first!.val
            }
            var secondVal = 0
            if second != nil {
                secondVal = second!.val
            }
            
            var val = firstVal + secondVal + overFlow
            if val>=10 {
                val -= 10
                overFlow = 1
            } else {
                overFlow = 0
            }
            
            let temp = ListNode.init(val)
            workNode.next = temp
            
            
            workNode = temp
            first = first?.next
            second = second?.next
        }
        
        return result.next
    }
}


下面还有一个类似的题目, 

2个非空链表相加,里面的元素都是int类型,

比如  (3->4->1) + (1->2) ,返回3->5->3,

这个题目和上面有点小不同, 把第一位认为是最高位, 可以用2个栈保存链表, 然后同时pop,这个可以保证pop出来的是同一位, 加出来的结果也加入到一个栈中, 然后在把结果栈转成链表返回即可.

class Solution {
    
    func addTwoNumbers(_ l1: ListNode?, _ l2: ListNode?) -> ListNode? {
        
        guard l1 != nil else {
            return l2
        }
        guard l2 != nil else {
            return l1
        }
        
        var firstArray = [Int]()
        var secondArray = [Int]()
        
        var first = l1
        var second = l2
        while first != nil {
            
            firstArray.append(first!.val)
            first = first?.next
        }
        while second != nil {
            
            secondArray.append(second!.val)
            second = second?.next
        }
        
        var resultArray = [Int]()
        var overFlow = 0
        
        while firstArray.count > 0 || secondArray.count > 0 || overFlow != 0 {
            
            let firstVal = firstArray.popLast() ?? 0
            let secondVal = secondArray.popLast() ?? 0
            
            
            var val = firstVal + secondVal + overFlow
            if val>=10 {
                val -= 10
                overFlow = 1
            } else {
                overFlow = 0
            }
            resultArray.append(val)

        }
        
        
        let result = ListNode.init(0)
        var workNode = result
        
        while resultArray.count > 0 {
            let temp = ListNode.init(resultArray.popLast()!)
            
            workNode.next = temp
            workNode = temp
        }

        
        return result.next
    }
    
}

发现竟然不是100%, 后续看了看其他人的代码, 确实存在优化的空间, 最后一个结果栈, 其实是没有必要的, 可以一边计算出结果,一边生成结果链表. 这样操作后可以节省一次循环的时间, 优化后就是超过100%了 

var result : ListNode!
var temp : ListNode!
var overFlow = 0
        
while firstArray.count > 0 || secondArray.count > 0 || overFlow != 0 {
         
    // 省略代码...... 还是原来的计算val     
    // 此处不需要结果栈了, 用temp保存结果链表的上一个节点, 然后串起来, 节省了一次循环的时间
    result = ListNode.init(val)
    
    if temp != nil {
        result.next = temp
    }
    temp = result
}
        
return result

除了常规解法, 还可以这样, 遍历把链表中的数据用一个真正的int表示出来, 然后2个int相加的结果为sum,在把sum转成一个链表输出.这个方案不用考虑那么多细节,进位啊,最后一位超出了处理啊统统不需要考虑. 简单直接, 但是慢一点点,而且不能处理超大数,不论是用处long还是int,对于位数过多的数字总是能超出使用范围导致无法处理的, 这个当然是无法通过测试用例的, 给出第一位是最低位的解法.

// 把链表的数据转出来,然后处理,需要O(m+n+最长的链表)
void fun1() {
    NSArray * first = @[@(1),@(5),@(9),@(6)];
    NSArray * second = @[@(3),@(9),@(2),@(4)];

    int firstInt = 0;
    for (int i = 0; i<first.count; i++) {
        NSNumber * num = first[i];
        firstInt += num.intValue * pow(10, i);
    }
    NSLog(@"第一个:%d",firstInt);
    
    int secondInt = 0;
    for (int i = 0; i<second.count; i++) {
        NSNumber * num = second[i];
        secondInt += num.intValue * pow(10, i);
    }
    NSLog(@"第二个:%d",secondInt);

    int sum = firstInt + secondInt;
    NSLog(@"结果:%d",sum);

    NSMutableArray * result = [[NSMutableArray alloc] init];
    while (sum>0) {
        [result addObject:@(sum%10)];
        sum = sum/10;
    }
    NSLog(@"%@",result);
    
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值