【LeetCode Medium系列】leetcode 2 Add Two Numers(附 c++ list and iterator介绍)
目录
1. 算法介绍:
题目要求如下:
本题目的解答思路就是传统的加法的计算过程,即对应位数相加,满十进一即可;需要注意的是:题目中给的是单链表,其具体的定义格式在代码上面的注释中。 下面先给出对应的代码,然后进行深入分析,顺便补充一下c++的一些基本知识。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode *head = new ListNode(0); //链表追加的时候需要新建
ListNode *l3 = head;
ListNode *p1 = l1;
ListNode *p2 = l2;
int carry = 0;
while(p1 != NULL || p2 != NULL) {
int sum = 0;
if(p1) { //取值的时候一定要看一下指针是否越界了!!
sum += p1->val;
p1 = p1->next;
}
if(p2) {
sum += p2->val;
p2 = p2->next;
}
sum += carry;
carry = sum / 10;
sum %= 10;
l3->next = new ListNode(sum);
l3 = l3->next;
}
if (carry == 1) {
l3->next = new ListNode(1);
l3 = l3->next;
}
return head->next;
}
};
代码需要注意的地方有:
1、在不熟练的情况下,可以先用样例跑一下不进位的例子,如果成功了,在修改为有进位的情况
2、指针的取值,一定要先检查是否越界!只有在不越界的情况下才可以进行取值操作!
3、链表追加的时候需要new一个List,不能直接用 l3->next;(因为在定义中其为NULL)
4、while循环中的内容,符合传统的加法运算的思路。即逐位相加,满十进一;
2. c++ STL中的list及其用法。
在看完题目以后,为了练习c++ STL中list的用法,在qt中进行了操作。程序的思路是,先将每个链表中的数,转化为整数,然后分别相加,最后将得到的结果按照题目要求的形式存放入列表中即可。先给出实现的代码,然后再介绍原理。
list<int> l1, l2, l;
//list<int>::iterator it1, it2;
l1.push_back(2);
l1.push_back(4);
l1.push_back(3);
l2.push_back(5);
l2.push_back(6);
l2.push_back(4);
//int len1 = l1.size();
//int len2 = l2.size();
int num1 = 0;
int num2 = 0;
int sum = 0;
int place = 0;
for (int i : l1){
// cout << " i = " << i << endl;
num1 += i * pow(10,place++);
}
place = 0;
for(int i : l2){
num2 += i* pow(10,place++);
}
sum = num1 + num2;
while(sum) {
l.push_back(sum % 10);
sum /= 10;
}
注意上述代码中for循环的写法,对于容器中元素的取值,在c++11以后变得非常方便,用for(:)的形式即可实现。相当于for_each语句,可以自动实现容器中元素的遍历。
以下地址是对c++中的STL中list的介绍,个人觉得挺适合初学者。
https://www.cnblogs.com/this-543273659/archive/2011/08/01/2123373.html
这篇文章对于初次接触STL或者初次使用C++ list的人来说非常有帮助。其介绍了STL的一些通用知识,如在STL的通用算法for_each来遍历iterator的范围,(相当于一个简写的for循环)
(注意:文中的代码,都没有命名空间的约束,在实际写的时候,还需要加入 using namespace std;)
3. c++迭代器 iterator介绍
部分内容参考了以下网址:https://blog.****.net/zhanh1218/article/details/33340959
每一种容器都定义了自己迭代器的类型,访问的方式都一样,
如list<string>::iterator it; (容器名字 + <数据类型> + ::iterator + 迭代器名字)( 是模板定义的格式;)
每种容器都定义了一对命名为 begin 和 end 的函数,用于返回迭代器。如果容器中有元素的话,由 begin 返回的迭代器指向第一个元素。注意:begin() 和 end()是容器的函数,其返回结果可以放入迭代器。
结合第二节中的内容,给出下列测试代码:
list<string> FruitAndVegetables;
FruitAndVegetables.push_back("carrot");
FruitAndVegetables.push_back("pumpkin");
FruitAndVegetables.push_back("potato");
FruitAndVegetables.push_front("apple");
FruitAndVegetables.push_front("pineapple");
list<string>::iterator it;//iterator相当于一个指针,因此没有it.end()等操作
cout << *FruitAndVegetables.end() << endl;// - FruitAndVegetables.begin() << endl;
for_each (FruitAndVegetables.begin(), FruitAndVegetables.end(), PrintIt);
for(it = FruitAndVegetables.begin(); it != FruitAndVegetables.end();++it) {
cout << *it << endl;
}
cout << "vector test --------\n";
vector<int> vec{1,24,5};
//vector<int>::iterator iter;
cout << vec.end() - vec.begin() << endl;
cout << *vec.begin() << endl;
// cout << *--vec.end() << endl;
/* end()函数使用须知:
* end函数指向不是最后一个元素(的地址),而是最后一个元素的下个位置,
* 因此如果使用iterator来遍历的时候,终止条件应该写为 != end();
* 如果容器为空,则end() - begin()为0;(顺序存放的容器可以使用end() - begin(),若容器是list,end-begin无效)
* 不用利用取地址符号直接访问end()中的元素(如果容器不为空,则可以利用begin函数访问容器的首元素(的地址))
* 如果容器是list,那么end函数是有意义的,其指向了倒数第二个元素,因为list是双向链表
*/
以上各部分内容都介绍的比较粗浅,等以后用到STL和iterator的时候再对该部分进行补充说明。也希望大家多多留言,共同进步提高。