码迷,mamicode.com
首页 > 其他好文 > 详细

leetcode -day8 Copy List with Random Pointer & Single Number I II

时间:2014-05-06 18:54:59      阅读:386      评论:0      收藏:0      [点我收藏+]

标签:leetcode   算法   

五一中间断了几天,开始继续。。。

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呢,只能通过模拟了。

对于除出现一次之外的所有的整数,其二进制表示中每一位1出现的次数是3的整数倍,将所有这些1清零,剩下的就是最终的数。
用ones记录到当前计算的变量为止,二进制1出现“1次”(mod 3 之后的 1)的数位。用twos记录到当前计算的变量为止,二进制1出现“2次”(mod 3 之后的 2)的数位。当ones和twos中的某一位同时为1时表示二进制1出现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,布布扣,bubuko.com

leetcode -day8 Copy List with Random Pointer & Single Number I II

标签:leetcode   算法   

原文地址:http://blog.csdn.net/kuaile123/article/details/25033809

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!