日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【LeetCode】2.两数相加

發布時間:2024/9/30 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【LeetCode】2.两数相加 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.兩數相加

一、問題描述

給你兩個?非空 的鏈表,表示兩個非負的整數。它們每位數字都是按照?逆序?的方式存儲的,并且每個節點只能存儲?一位?數字。

請你將兩個數相加,并以相同形式返回一個表示和的鏈表。

你可以假設除了數字 0 之外,這兩個數都不會以 0?開頭。

二、問題簡化

這個問題實際上是為了解決大數計算問題,即比較大的數字的計算(眾所周知int型的表示范圍有限)。

很明顯題目說的是十進制,實際其他進制也是一樣的。

十進制一位只有10個值,用4位2進制就足夠表示了,也就是32位可以表示8個十進制。不過int型的計算是快于其他類型的(由于硬件的架構),所以先不考慮這么多,使用int型的鏈表表示大數類即可:

typedef list<int> BigInteger;

在定義大數類之后,求和函數傳入兩個值,返回一個值,如下::

BigInteger addTwoNumber(const BigInteger& a, const BigInteger& b)

?三、功能實現

基本算法

1.首先區分出長鏈和短鏈,也就是哪個數字更短。

2.遍歷短鏈,同時遍歷長鏈,之間相加的結果插入到結果鏈,并記錄是否進位(很明顯,進位只能進1)。

3.將長鏈剩余部分添加到結果鏈,同時也可能發生進位。

4.最后還可能進位,最后單獨判斷一次

BigInteger addTwoNumber(const BigInteger& a, const BigInteger& b) {BigInteger ret;const BigInteger* bi_s;const BigInteger* bi_l;//區分長短鏈if (a.size() > b.size()){bi_l = &a;bi_s = &b;}else{bi_l = &b;bi_s = &a;}//取較小長度int length = bi_s->size();//0為短鏈auto iter0 = bi_s->begin();auto iter1 = bi_l->begin();//是否進位標記bool carry = false;//遍歷完短鏈for (int i = 0; i != length; ++i){//求和int sum = *iter0 + *iter1;//如果上次遍歷結果進位,則加1if (carry) ++sum;if (sum < 10)carry = false;//否則不進位else{//如果結果大于等于10,則進位(標記進位,下次循環使用)sum %= 10;carry = true;}ret.push_back(sum);++iter0;++iter1;}//再添加較長數字的剩余高位(考慮進位)for (; iter1 != bi_l->end(); ++iter1){if (carry){//進位則加1,同時還可能發生繼續進位int num = *iter1 + 1;if (num < 10)carry = false;elsenum %= 10;ret.push_back(num);}else{ret.push_back(*iter1);carry = false;}}//最后進位可能if (carry){ret.push_back(1);}return ret; }

?打印功能

需要直觀的觀察數字,所以我們用逆序迭代器打印每一個節點,以及直接打印出a加b的結果:

void PrintNumber(const BigInteger& bi) {//逆序打印for (auto iter = bi.rbegin(); iter != bi.rend(); ++iter){cout << *iter;} }void PrintNumberAdd(const BigInteger& a, const BigInteger& b) {auto ret = addTwoNumber(a, b);PrintNumber(a);cout << " add ";PrintNumber(b);cout << " is equal ";PrintNumber(ret);cout << "." << endl; }

四、測試結果

?

代碼如下(網上的代碼看上去比較簡潔,但是并沒有拆分步驟,而是在循環內多次進行判斷和求和,我的代碼效率必然會更快一些,不過不是數量級的變化):

//2.兩數之和#include <list> #include <iostream> using namespace std;typedef list<int> BigInteger;BigInteger addTwoNumber(const BigInteger& a, const BigInteger& b) {BigInteger ret;const BigInteger* bi_s;const BigInteger* bi_l;//區分長短鏈if (a.size() > b.size()){bi_l = &a;bi_s = &b;}else{bi_l = &b;bi_s = &a;}//取較小長度int length = bi_s->size();//0為短鏈auto iter0 = bi_s->begin();auto iter1 = bi_l->begin();//是否進位標記bool carry = false;//遍歷完短鏈for (int i = 0; i != length; ++i){//求和int sum = *iter0 + *iter1;//如果上次遍歷結果進位,則加1if (carry) ++sum;if (sum < 10)carry = false;//否則不進位else{//如果結果大于等于10,則進位(標記進位,下次循環使用)sum %= 10;carry = true;}ret.push_back(sum);++iter0;++iter1;}//再添加較長數字的剩余高位(考慮進位)for (; iter1 != bi_l->end(); ++iter1){if (carry){//進位則加1,同時還可能發生繼續進位int num = *iter1 + 1;if (num < 10)carry = false;elsenum %= 10;ret.push_back(num);}else{ret.push_back(*iter1);carry = false;}}//最后進位可能if (carry){ret.push_back(1);}return ret; }void PrintNumber(const BigInteger& bi) {//逆序打印for (auto iter = bi.rbegin(); iter != bi.rend(); ++iter){cout << *iter;} }void PrintNumberAdd(const BigInteger& a, const BigInteger& b) {auto ret = addTwoNumber(a, b);PrintNumber(a);cout << " add ";PrintNumber(b);cout << " is equal ";PrintNumber(ret);cout << "." << endl; }int main() {//test0list<int> a = { 1,1,2,4,0,0,0,0 };//4211list<int> b = { 0,4,8,5,1,7 };//715840//求和并打印PrintNumberAdd(a, b);//test1a = { 1,2,3,4,5,6,7,8,9 };//987654321b = { 4,4,4,4 };//4444//求和并打印PrintNumberAdd(a, b);//test2a = { 2,5,9,0,0,0,1 };//1000925b = { 6,7 };//76//求和并打印PrintNumberAdd(a, b);//test3a = { 9,9,9 };//999b = { 1,1,1 };//111//求和并打印PrintNumberAdd(a, b);//test4a = {};//b = {};////求和并打印PrintNumberAdd(a, b); }

總結

以上是生活随笔為你收集整理的【LeetCode】2.两数相加的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。