列表以及字符串加法

dcq.jpeg

You are given two linked lists representing two non-negative numbers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)

Output: 7 -> 0 -> 8


这个问题比较核心的一点是对进位(carry)的处理,处理好了进位(carry)也就没什么难度了。
同时,还要注意一下几个特殊的链表

  1. 两个不一样长的

    l1 = [0, 1];

    l2 = [0, 1, 2];

  2. 有一个是空列表的情况

    l1 = []

    l2 = [0, 1]

  3. 多次进位的情况(这个状况是最容易被遗漏的)

    l1 =[9, 9]

    l2 = [1]

直接上代码

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
            if (l1 == null)
                if(l2 != null) {
                    return addTwoNumbers(l2, new ListNode(0));
                } else {
                    return null;
                }
            if (l2 == null) {
                if(l1!=null) {
                    return addTwoNumbers(l1, new ListNode(0));
                } else {
                    return null;
                }
            }
            int val = l1.val + l2.val;
            ListNode head = new ListNode(val%10);
            int carry = val / 10;
            if(carry > 0) {
                if(l1.next == null) {
                    l1.next = new ListNode(carry);
                } else {
                    l1.next.val += carry;
                }
            }
            head.next = addTwoNumbers(l1.next, l2.next);
            return head;
      }

扩展一下

Given two binary strings, return their sum (also a binary string).

For example,

a = "11"

b = "1"

Return "100".

类似于二进制的加法核心跟上一个算法没有太多区别。


 public String addBinary(String a, String b) {
        if(a == null || a.equals(""))return b;
        if(b == null || b.equals(""))return a;
        StringBuilder stringBuilder = newStringBuilder();
        int i = a.length() - 1;
        int j = b.length() - 1;
        int carry = 0;
        while (i >= 0 || j >= 0) {
            int sum = carry;
            if(i >= 0) sum += a.charAt(i--)- '0';
            if(j >= 0) sum += b.charAt(j--)- '0';
            stringBuilder.append(sum%2);
            carry = sum / 2;
        }
        if(carry != 0)stringBuilder.append(carry);
        return stringBuilder.reverse().toString();
    }

结束了加法,我们来看看乘法

Given two numbers represented as strings, return multiplication of the numbers as a string.

Note:

  • The numbers can be arbitrarily large and are non-negative.
  • Converting the input string to integer is NOT allowed.
  • You should NOT use internal library such as BigInteger.

这里我们观察一下,能得到结论:

num1[i] 和num2[j] 的乘积会放置在indices[i+j, i+j+1]的位置

说起来比较抽象,我们看图:

字符串乘法演示.jpg

代码实现如下:

public String multiply(String num1, String num2) {
    int m = num1.length(), n = num2.length();
    int[] pos = new int[m + n];
   
    for(int i = m - 1; i >= 0; i--) {
        for(int j = n - 1; j >= 0; j--) {
            //错位相加
            int mul = (num1.charAt(i) - '0') * (num2.charAt(j) - '0'); 
            int p1 = i + j, p2 = i + j + 1;
            int sum = mul + pos[p2];
            pos[p1] += sum / 10;
            pos[p2] = (sum) % 10;
        }
    }  
    
    StringBuilder sb = new StringBuilder();
    for(int p : pos) if(!(sb.length() == 0 && p == 0)) sb.append(p);
    return sb.length() == 0 ? "0" : sb.toString();
}

更清晰的代码实现:

public Stringmultiply(String num1, String num2) {
        char[] s1 = num1.toCharArray();
        char[] s2 = num2.toCharArray();
        int len1 = s1.length;
        int len2 = s2.length;
        int[] ans = new int[len1 + len2];
        for (int i = len2 - 1; i >= 0; i--){
            for (int j = len1 - 1; j >= 0;j--) {
                ans[len1 + len2 - i - j - 2] +=(s2[i] - '0') * (s1[j] - '0');
            }
        }

        for (int i = 0; i < len1 + len2 - 1;i++) {
            ans[i + 1] += ans[i] / 10;
            ans[i] %= 10;
        }

        StringBuilder stringBuilder = newStringBuilder();
        int i = len1 + len2 - 1;
        while (i >= 0 && ans[i] ==0)
            i--;
        if (i < 0)
            return "0";
        while (i >= 0) {
            stringBuilder.append(ans[i]);
            i--;
        }
        return stringBuilder.toString();

    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容

  • 背景 一年多以前我在知乎上答了有关LeetCode的问题, 分享了一些自己做题目的经验。 张土汪:刷leetcod...
    土汪阅读 12,723评论 0 33
  • **2014真题Directions:Read the following text. Choose the be...
    又是夜半惊坐起阅读 9,369评论 0 23
  • 中午起床的孩子不想吃饭可以试试这个白粥你,是感冒没胃口最好的食粮了! 首先将猪肉剁成肉沫,根据个人喜好调整肉沫的细...
    kanoko阅读 244评论 3 1
  • 高中过后,舒服自由的日子就来了,没有繁重的作业,没有家长老师的叮咛,一切生活随心所欲。迎来生命第二春(第一春在襁褓...
    子暮言阅读 365评论 4 2
  • 我从未如此认真的感到荣幸 虔诚翘首,顶礼膜拜 一步一叩头 一步一作揖 唐卡之上的风马旗咧咧作响 我则如同一个喇嘛 ...
    Mr橘子阅读 328评论 4 2