2018.3.8
1.Two Sum
第一次尝试,ruby,看似简单却忽略了例如6=3+3的情况。
第二次尝试,ruby,缺少数组方面去掉一个元素的知识,但又不能真的去掉,因为下一次循环还要使用,以及需要返回第二个数的标号。
第三次尝试,C,没有注意上面的malloc要求。
第四次尝试,C,AC。但时间复杂度为O(n²)
看了discuss之后,发现哈希很好用,的确能把复杂度从O(n²)降到O(n)。
C++的Map容器和Python字典。
C++ :unordered_map<int,int> hash;hash[nums[i]]=i;if(hash.find(num)!=hash.end())
/*hash的声明、赋值和查找是否存在key值。*/
容器 vector<int> result;result.push_back(i);
Python:for i,num in enumerate(nums);//同时查找标号和值。
dict={};dict[num]=i;return [dict[num],i]//简直太简洁。
特别说明:当hash表在查找结束后才插入,可以顺便有效解决第一次尝试时出现的问题。当发现第一个3时,hash表中并没有3,因此进入下一次循环,当再次发现3,hash表中已经有3了,而且这个3肯定不是现在这个3而是以前有过一个3被添进hash表里了。如果是先把hash表填好再进行查找,同样需要注意一中的问题。
2018.3.14
2.Add Two numbers
第一次尝试,C
present->val=(present->val+caryy)%10;
carry=(present->val+carry)/10;
present->val已经被改变,所以会出错,可以增加一个中间变量保存;看完solution发现,其实可以sum=present->val+carry;present->val=sum%10;carry=sum/10;
member access within misaligned address 0x000000000031 for type 'struct ListNode', which requires 8 byte alignment
问题原因:malloc结构体以后,里面的next随机指向,应该及时赋空。(没有初始化的指针指向一个随机的地址)
指针及时初始化是个好习惯!!
第二次尝试,C,将链表1改为结果链表,节约空间,最多增加一个结构体空间
discuss
https://leetcode.com/problems/add-two-numbers/discuss/1092/A-horrible-hack-in-C-16ms
while(l1||l2){
if(l1){s+=l1->val;l1=l1->next;}
if (l2){s+=l2->val;l2=l2->next; }
}这个办法很好地融合了其中一条链长的问题,即使有多次进位也能一起解决,的确简洁了不少。
同时,最开始的struct ListNode* carry = l1 ? l2 : l1;很好地解决了最后仍有进位的问题,如果l1本来就是空,就不可能出现这种情况,否则,一定l2的第一个结点没有被result使用,的确周密又节约。
https://leetcode.com/problems/add-two-numbers/discuss/1180/My-solution-in-C
一行声明多个指针struct ListNode* res, *L1=l1, *L2=l2, *temp;自己第一次写的时候忘了在之后的变量名前加*,编译不通过。
先求和,再进位。两条链都存和,res选择长的那条。
没有丢了l1和l2这两个链头也值得学习。
https://leetcode.com/problems/add-two-numbers/discuss/1626/12ms-c-solution
这个也蛮好的,一个循环就解决了,连多余进位也一起解决了,方法是,第一个结点的malloc放外面。每次用到结点的数据时都判断一下指针是否为空。可以说很优雅了。
Python:
https://leetcode.com/problems/add-two-numbers/discuss/1071/Python-solution-short-and-simple
简洁明了的Python解法。
carry= divmod(v1+v2+carry, 10)
n.next = ListNode(val)
carry //= 10(Python中“//”为运算符,功能为 取整除 - 返回商的整数部分)
https://leetcode.com/problems/add-two-numbers/discuss/1102/Python-for-the-win
2018.06.24
7.Reverse Integer
主要是考虑overflow的问题。整型的范围是-2^31~2^31-1也就是[-2147483648,2147483647]。
由于y=y*10+tmp,可以由当前y判断下一个y是否溢出,若溢出则返回0。因此有:
if(y>INT_MAX/10 || (y==INT_MAX/10 && tmp>7)) return 0;
if(y<INT_MIN/10 || (y==INT_MIN/10 && tmp<-8)) return 0;
Python,有个reverse的简单办法[::-1]。这是对list进行操作:
b=a[i:j:s] //i是起始下标,j是末下标,s表示步进。当s为负数时,i默认为-1(即最后一个元素),j默认为-len(a)(即第一个元素)。
b=a[i:j] //i默认为0,j默认为len(a)-1