五一中间断了几天,开始继续。。。
1、
Copy List with Random Pointer
A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.
Return a deep copy of the list.
分析:剑指offer上的一道题目,分三步进行,首先复制每个链表结点将其连接在每个结点之后,第二步拷贝指向随机节点的指针,第三部拆分链表。
代码如下:
/** * Definition for singly-linked list with a random pointer. * struct RandomListNode { * int label; * RandomListNode *next, *random; * RandomListNode(int x) : label(x), next(NULL), random(NULL) {} * }; */ class Solution { public: RandomListNode *copyRandomList(RandomListNode *head) { if(head == NULL){ return NULL; } cloneNodes(head); connectRandomNodes(head); return reconnectNodes(head); } void cloneNodes(RandomListNode *head){ RandomListNode* pNode = head; while(pNode!=NULL){ RandomListNode* pClonedNode = new RandomListNode(pNode->label); pClonedNode->next = pNode->next; pNode->next = pClonedNode; pNode = pClonedNode->next; } } void connectRandomNodes(RandomListNode *head){ RandomListNode* pNode = head; while(pNode!=NULL){ RandomListNode* pClonedNode = pNode->next; RandomListNode* pRandomNode = pNode->random; if(pRandomNode != NULL){ pClonedNode->random = pRandomNode->next; } pNode = pClonedNode->next; } } RandomListNode* reconnectNodes(RandomListNode *head){ RandomListNode* pNode = head; RandomListNode* pNextNode = pNode->next; RandomListNode* pClonedHead = pNode->next; while(pNode!=NULL && pNextNode!=NULL){ pNode->next = pNextNode->next; pNode = pNextNode; pNextNode = pNextNode->next; } return pClonedHead; } };
2、Single Number
Given an array of integers, every element appears twice except for one. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
分析:寻找数组中其他出现两次只有一个数字出现一次是个很常见的题目,很简单,所有数字亦或,最后的结果为只出现一次的数字。
代码如下:
class Solution { public: int singleNumber(int A[], int n) { if(A==NULL || n<=0){ return 0; } int result = A[0]; for(int i=1;i<n;++i){ result ^= A[i]; } return result; } };
3、Single Number II
Given an array of integers, every element appears three times except for one. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
分析:除了一个数字出现一次外其余数字出现三次,两次上面已经求过很好算,三次怎么得到0呢,想到mod 3,肯定是通过位运算来处理。那么位运算如何得到mod 3呢,只能通过模拟了。
用二进制模拟三进制计算 。最终ones记录的是最终结果。
class Solution { public: int singleNumber(int A[], int n) { int ones = 0, twos = 0, threes = 0; for(int i = 0; i < n; i++) { threes = twos & A[i]; //已经出现两次并且再次出现 twos = twos | ones & A[i]; //曾经出现两次的或者曾经出现一次但是再次出现的 ones = ones | A[i]; //出现一次的 twos = twos & ~threes; //当某一位出现三次后,我们就从出现两次中消除该位 ones = ones & ~threes; //当某一位出现三次后,我们就从出现一次中消除该位 } return ones; //twos, threes最终都为0.ones是只出现一次的数 } };
4、Two Sum
Given an array of integers, find two numbers such that they add up to a specific target number.
The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.
You may assume that each input would have exactly one solution.
Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2
分析:在一个数组中找两个数,使其和为目标值,如果循环遍历复杂度为O(n^2),可以采用先排序再用双指针法进行查找。考虑到vector的iterator是random iterator可以使用自带的sort进行排序,但是排序后vector的元素位置改变,不符合题意;然后考虑到将数据保存到map中,键值为vector中的数值,数值为vector中的索引+1(输出索引从1开始)。
注意使用map时因为vector中的元素可以重复,所以应该使用multimap,而且stl中 的红黑树的end()是个空值,所以双指针时要注意尾指针的赋值。这样的复杂度为O(nlgn)。
代码如下:
class Solution { public: vector<int> twoSum(vector<int> &numbers, int target) { vector<int> resultVec; if(numbers.empty()){ return resultVec; } multimap<int,int> numberMap; for(int i=0; i<numbers.size(); ++i){ numberMap.insert(make_pair(numbers[i],i+1)); } //sort(numbers.begin(),numbers.end()); multimap<int,int>::iterator iter1 = numberMap.begin(); multimap<int,int>::iterator iter2 = numberMap.end(); --iter2; int sum = 0; while(iter1!=iter2){ sum = iter1->first+iter2->first; if(sum == target){ int index1 = iter1->second; int index2 = iter2->second; if(index1>index2){ swap(index1,index2); } resultVec.push_back(index1); resultVec.push_back(index2); break; }else if(sum >target){ --iter2; }else{ ++iter1; } } return resultVec; } };
leetcode -day8 Copy List with Random Pointer & Single Number I II