LeetCode 445. Add Two Numbers II(兩數(shù)相加 java)

給定兩個非空鏈表來代表兩個非負(fù)整數(shù)犹菱。數(shù)字最高位位于鏈表開始位置绕辖。它們的每個節(jié)點只存儲單個數(shù)字胖腾。將這兩數(shù)相加會返回一個新的鏈表霍比。

你可以假設(shè)除了數(shù)字 0 之外幕袱,這兩個數(shù)字都不會以零開頭。

進(jìn)階:

如果輸入鏈表不能修改該如何處理悠瞬?換句話說们豌,你不能對列表中的節(jié)點進(jìn)行翻轉(zhuǎn)。

示例:

輸入: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4)
輸出: 7 -> 8 -> 0 -> 7

思路:

  1. 毫無疑問,難點在于進(jìn)位的處理,不需要進(jìn)位的情況下,僅僅只是簡單的同位相加
  2. 由于鏈表無法逆向遍歷,需要通過其他手段輔助定位,如:鏈表反轉(zhuǎn),集合. 也可以通過轉(zhuǎn)為10進(jìn)制進(jìn)行操作,不過這也是效率較低的選擇(注意溢出)
  3. 在不知曉鏈表長度情況下,重建鏈表的效果要高于在原立案表上進(jìn)行改動

代碼1:

public ListNode addTwoNumbers1(ListNode l1, ListNode l2) {
        if (l1 == null || l2 == null)
            return l1;
        ListNode temp = l1, cur;
        long num1 = 0, num2 = 0;
        //轉(zhuǎn)為十進(jìn)制數(shù)
        while (temp != null) {
            num1 = num1 * 10 + temp.val;
            temp = temp.next;
        }
        temp = l2;
        while (temp != null) {
            num2 = num2 * 10 + temp.val;
            temp = temp.next;
        }
        //求和并重構(gòu)鏈表
        num1 = num1 + num2;
        if (num1 > 0) {
            ListNode res = new ListNode(0);
            res.next = temp;
            int k;
            while (num1 != 0) {
                k = (int) (num1 % 10);
                cur = res.next;
                temp = new ListNode(k);
                res.next = temp;
                temp.next = cur;
                num1 = num1 / 10;
            }
        } else {
            temp = new ListNode(0);
        }
        return temp;
    }

分析:

  • 將鏈表轉(zhuǎn)為十進(jìn)制,自動進(jìn)位進(jìn)位處理,思路非常簡單
  • 測試用例中有許多越界數(shù)組,該方法還需要添加溢出的處理,例如按位數(shù)用數(shù)組分批存儲數(shù)字等

代碼2

    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        Stack<Integer> sta1 = new Stack<Integer>();
        Stack<Integer> sta2 = new Stack<Integer>();
        Stack<Integer> sta = new Stack<Integer>();
        //構(gòu)建棧
        while (l1 != null) {
            sta1.push(l1.val);
            l1 = l1.next;
        }
        while (l2 != null) {
            sta2.push(l2.val);
            l2 = l2.next;
        }
        int c = 0;
        //相加進(jìn)位,壓入新棧
        while (!sta1.isEmpty() && !sta2.isEmpty()) {
            int sum = sta1.pop() + sta2.pop() + c;
            c = sum / 10;
            sum = sum % 10;
            sta.push(sum);
        }
        if (!sta2.isEmpty())
            sta1 = sta2;
        //為了應(yīng)對兩鏈表長度不同,另開一個循環(huán)進(jìn)行處理
        while (!sta1.isEmpty()) {
            int sum = sta1.pop() + c;
            c = sum / 10;
            sum = sum % 10;
            sta.push(sum);
        }
        if (c == 1)
            sta.push(1);
        ListNode dump = new ListNode(0);
        ListNode ret = dump;
        while (!sta.isEmpty()) {
            dump.next = new ListNode((int) sta.pop());
            dump = dump.next;
        }
        return ret.next;
    }

分析:

  • 使用棧進(jìn)行操作,通過出棧操作達(dá)到逆向遍歷鏈表的目的
  • 此處也可以使用list等其他存儲集合,但是效率都很低

代碼3:

    public ListNode addTwoNumbersBest(ListNode l1, ListNode l2) {
        ListNode root1 = exec(l1);
        ListNode root2 = exec(l2);
        
        ListNode root = null, current = null;
        int bits = 0;
        ListNode n1 = root1, n2 = root2;
        for(;n1 != null && n2 != null;n1 = n1.next, n2 = n2.next) {
            int value = n1.val + n2.val + bits;
            bits = value / 10;
            
            if(root == null) {
                root = new ListNode(value % 10);
                current = root;
            }else {
                current.next = new ListNode(value % 10);
                current = current.next;
            }
        }
        
        for(;n1 != null;n1 = n1.next) {
            int value = n1.val + bits;
            bits = value / 10;
            
            current.next = new ListNode(value % 10);
            current = current.next;
        }
        
        for(;n2 != null;n2 = n2.next) {
            int value = n2.val + bits;
            bits = value / 10;
            
            current.next = new ListNode(value % 10);
            current = current.next;
        }
        
        if(bits != 0) {
            current.next = new ListNode(bits);
            current = current.next;
        }
        return exec(root);
    }
    //反轉(zhuǎn)方法
    public ListNode exec(ListNode root) {
        ListNode node = root, previous = null;
        while(node != null) {
            ListNode next = node.next;
            node.next = previous;
            previous = node;
            node = next;
        }
        return previous;
    }

分析:

  • 執(zhí)行效率分布中非城匙保靠前的方法
  • 先反轉(zhuǎn)鏈表,使其可以逆向遍歷,之后使用相同的處理方式,計算和值

總結(jié):

  1. 本題主要考察當(dāng)順序遍歷無法滿足結(jié)題要求時,對數(shù)據(jù)的處理方法
  2. 逆向鏈表與棧都是非常好的方法,若使用轉(zhuǎn)為十進(jìn)制進(jìn)行操作,需要處理數(shù)值溢出問題
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末望迎,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子狂打,更是在濱河造成了極大的恐慌擂煞,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件趴乡,死亡現(xiàn)場離奇詭異对省,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)晾捏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進(jìn)店門蒿涎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人惦辛,你說我怎么就攤上這事劳秋。” “怎么了胖齐?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵玻淑,是天一觀的道長。 經(jīng)常有香客問我呀伙,道長补履,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任剿另,我火速辦了婚禮箫锤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘雨女。我一直安慰自己谚攒,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布氛堕。 她就那樣靜靜地躺著馏臭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪讼稚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天,我揣著相機(jī)與錄音宾肺,去河邊找鬼文黎。 笑死,一個胖子當(dāng)著我的面吹牛痛倚,可吹牛的內(nèi)容都是我干的规婆。 我是一名探鬼主播,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蝉稳,長吁一口氣:“原來是場噩夢啊……” “哼抒蚜!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起耘戚,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤嗡髓,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后收津,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體饿这,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年撞秋,在試婚紗的時候發(fā)現(xiàn)自己被綠了长捧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡吻贿,死狀恐怖串结,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情舅列,我是刑警寧澤肌割,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站帐要,受9級特大地震影響把敞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜宠叼,卻給世界環(huán)境...
    茶點故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一先巴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧冒冬,春花似錦伸蚯、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至横侦,卻和暖如春挥萌,著一層夾襖步出監(jiān)牢的瞬間绰姻,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工引瀑, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留狂芋,地道東北人。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓憨栽,卻偏偏與公主長得像帜矾,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子屑柔,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 一些概念 數(shù)據(jù)結(jié)構(gòu)就是研究數(shù)據(jù)的邏輯結(jié)構(gòu)和物理結(jié)構(gòu)以及它們之間相互關(guān)系屡萤,并對這種結(jié)構(gòu)定義相應(yīng)的運算,而且確保經(jīng)過這...
    Winterfell_Z閱讀 5,791評論 0 13
  • 我和你說掸宛,你真是一個再好不過的人死陆,我走遍世界也找不到,你太好了唧瘾。 ...
    芭蕾裙下閱讀 650評論 0 0
  • 我與母親的關(guān)系就像一條曲線劈愚,一開始親密無間瞳遍,后來分成兩條不在一個方向的線,漸漸梳離菌羽,久了又會沿著同一個方向平...
    與雪樵閱讀 331評論 5 6
  • 每年寒暑假放假回家的時候掠械,烏盛都對自己的房間是不抱期望的。 要說這個不抱期望的深層含義是什么呢注祖?大概就是猾蒂,八年前,...
    蘸蘸閱讀 463評論 0 0
  • 魏慶軍緣 前世是晨,我是你親手種下得蓮 別的蓮 都開了 直到枯萎也沒能把我清秀得容顏 展現(xiàn) 在你的眼前 來生肚菠,千萬次的...
    慶軍_a3d7閱讀 114評論 0 0