两数相加_力扣_算法

在这里插入图片描述

  • 解法1
    尝试以下解法: 以下解法存在一个问题,就是当链表节点过多的时候,将字符串转换Long会报异常,总体思路上行得通。要改进的话,还需要对大整数的相加操作进行处理。解法1不是正确答案,因为不能完成长链表的数相加…超出int、long范围那种大整数计算不了。
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        List<Integer> list1 = new ArrayList<>();
        this.getList(l1,list1);
        list1 = this.reverse(list1);

        List<Integer> list2 = new ArrayList<>();
        this.getList(l2,list2);
        list2 = this.reverse(list2);

        long i1 = this.getIntNum(list1);
        long i2 = this.getIntNum(list2);

        long tol = i1 + i2;
        String str = tol + "";
        int len = str.length();
        int [] arr = new int[len];
        for(int n=0;n<len;n++){
            arr[len-1-n]=Integer.parseInt(str.substring(n,n+1));
        }
        ListNode nodeA = new ListNode(arr[0]);
        this.dg(arr,nodeA);
        return nodeA;
    }
	//根据链表获取链表中的值,按顺序存入list
    private void getList(ListNode l,List<Integer> list){
        list.add(l.val);
        if(l.next!=null){
            getList(l.next,list);
        }
    }
	//根据字符串获取数字,再进行相加,此处容易出现转换异常(数字大小超出int、long范围)
    private Long getIntNum(List<Integer> list){
        StringBuilder sb = new StringBuilder();
        for(Integer i : list){
            sb.append(i);
        }
        return Long.parseLong(sb.toString());
    }
	//将list中的内容反转一下,调换顺序
    private List<Integer> reverse(List<Integer> list){
        List<Integer> temp = new ArrayList<>();
        int s = list.size();
        for(Integer i : list){
            temp.add(i);
        }
        for(int i=0;i<s;i++){
            temp.set(s-i-1,list.get(i));
        }
        return temp;
    }

    int h = 1;
    //递归方法根据val值创建链表
    private void dg(int []arr,ListNode nodeA){
        if(h<arr.length){
            ListNode nodeB = new ListNode(arr[h]);
            nodeA.next=nodeB;
            h++;
            this.dg(arr,nodeB);
        }
       

    }
}
  • 解法2
    经过解法1的思路提醒,发现反复的调换顺序浪费了时间,所以就不用调换顺序,而且不整理放数组,直接利用ArrayList的有序性进行各位相加的操作,再判断进位。值得注意的是,最后一次的进位还需要再加上1.。。(当时5+5,本应输出10,但输出的是0,后面那个1因为循环超出数组的范围了,所以尽管将进位标志设为true,但还是没有将进位算进去,解决办法是跳出循环后再判断一次进位标志。)
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution2 {
    private int h = 1;
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        List<Integer> list1 = new ArrayList<>();
        this.getList(l1,list1);

        List<Integer> list2 = new ArrayList<>();
        this.getList(l2,list2);

        List<Integer> ln = this.addList(list1,list2);

        ListNode nodeA = new ListNode(ln.get(0));

        this.dg2(ln,nodeA);
        return nodeA;
    }

    private void getList(ListNode l,List<Integer> list){
        list.add(l.val);
        if(l.next!=null){
            getList(l.next,list);
        }
    }

    //根据输入的两个顺序的list进行相加,求得和的list
    //好像可以不用反转,两个反序的list就行,还省去了反转的操作,因为第一个值就是各位啊哈哈哈哈哈
    private List<Integer> addList(List<Integer> l1,List<Integer> l2){
        List<Integer> ln = new ArrayList<>();
        int s1 = l1.size(),s2 = l2.size();
        int smax = s1 >= s2 ? s1 : s2;
        int smin = s1 <= s2 ? s1 :s2;
        //从个位开始相加,取得的值放入
        boolean isAddOne = false;
        for(int i=0;i<smax;i++){
            if(i<smin){
                if(isAddOne){
                    int i1 = l1.get(i) + l2.get(i)+1;
                    ln.add(i1%10);
                    isAddOne = false;
                    if(i1>=10){
                        isAddOne = true;
                    }
                }else {
                    int i1 = l1.get(i) + l2.get(i);
                    ln.add(i1%10);
                    if(i1>=10){
                        isAddOne = true;
                    }
                }
            }else {
                if(s1==smax){
                    if(isAddOne){
                        int i1 = l1.get(i)+1;
                        ln.add(i1%10);
                        isAddOne = false;
                        if(i1>=10){
                            isAddOne = true;
                        }
                    }else {
                        ln.add(l1.get(i));
                    }
                }else {
                    if(isAddOne){
                        int i1 = l2.get(i)+1;
                        ln.add(i1%10);
                        isAddOne = false;
                        if(i1>=10){
                            isAddOne = true;
                        }
                    }else {
                        ln.add(l2.get(i));
                    }
                }
            }

        }
        if(isAddOne){
            ln.add(1);
        }
        return  ln;
    }

    /**
     *	根据list递归创建单向链表
     * @param ln
     * @param nodeA
     */
    private void dg2(List<Integer> ln,ListNode nodeA){
        if(h<ln.size()){
            ListNode nodeB = new ListNode(ln.get(h));
            nodeA.next=nodeB;
            h++;
            this.dg2(ln,nodeB);
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值