编程新手,尽量保证每天至少3道leetcode题,有些东西没有深入理解后面随着时间推移慢慢也就忘了,因此在此记录一下,一则督促自己完成每日任务,二则方便之后再来回顾,尽量用多种思路来分析解决问题,不足之处还望指出。
今日题目:1、查找数组相同元素;2、求交集;3、反转单向链表。
Given an array of integers, find if the array contains any duplicates. Your function should return true if any value appears at least twice in the array, and it should return false if every element is distinct.
题意:给一个整型的数组,找到是否包含相同元素
思路:
1、最容易想到的思路,类似冒泡排序暴力破解,只不过不是比较两个元素的大小换成比较两个元素是否相等,时间复杂度O(N),空间复杂度O(1);
2、对输入数组进行排序,然后再比较相邻元素,时间复杂度O(NlogN),空间复杂度O(1);
3、建立一个空的哈希表,遍历一次输入数组,如果值在哈希表中已经存在,返回true,如果不在就加入哈希表,如果遍历完了就返回false表明不存在相同元素,时间复杂度O(N),空间复杂度O(N);
4、建立一个STL的集合,将数组放入集合,如果数组的大小大于集合的大小,说明存在返回true,否则false;
代码:
C++:
class Solution {
public:
bool containsDuplicate(vector<int>& nums) {
return nums.size() > set<int>(nums.begin(), nums.end()).size();
}
};
结果:48ms,Your runtime beats 57.00% of cppsubmissions
python:
class Solution(object):
def containsDuplicate(self, nums):
""" :type nums: List[int] :rtype: bool """
return len(nums)>len(set(nums))
结果:64ms,Your runtime beats 34.97% of pythonsubmissions.
Given two arrays, write a function to compute their intersection.
Example:
Given nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2, 2].
题意:求两个列表的交集,如果重复次数大于1就将所有结果都方进来
思路:1、暴力法,两个集合元素两两比较,如果碰到相同元素就都剔除相同元素,Time: O(MN) Space: O(1),用元素较多的集合去元素较少的集合中遍历会快一点;2、建一个包含A、B所有元素在内的O(M+N)哈希表,先遍历A集合,相应位++,在遍历B集合的时候,做一次相应位–并判断是否为0,如果是就找到一个相同元素,Time: O(M+N) Space: O(M+N);
3、可以对2进行一些小小的优化,只建立包含A元素的哈希表,先遍历A相应位++,然后在遍历B中元素时候先进行一边查找,只有同时满足既在A中同时相应位–之后还大于等于0的条件才为找到一个元素,Time: O(m + n) Space: O(m);
4、现对A和B分别做一次排序,这个时候A、B中元素都是有序的了,然后从各自的第一个元素开始,比较相应元素,相等则找到一个元素,各自后移一个元素,不想等则哪个集合的元素大就后移另外一个集合的元素,Time: O(max(m, n) log(max(m, n))) Space: O(m + n)。
代码:
class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
int size1 = nums1.size();
int size2 = nums2.size();
sort(nums1.begin(),nums1.end());
sort(nums2.begin(),nums2.end());
int i=0,j=0;
vector<int>result;
while(i<size1&&j<size2)
{
if (nums1[i]==nums2[j])
{
result.push_back(nums1[i]);
i++;
j++;
}
else if(nums1[i]>nums2[j])
j++;
else
i++;
}
return result;
}
};
结果:Your runtime beats 37.99% of cppsubmissions.
Reverse a singly linked list.
题意:反转一个单向链表
思路:
1、自己写的很丑的代码,利用一个节点来存下一个节点
代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head==NULL||head->next==NULL)
return head;
ListNode* pNode,*pNext,*tmp;
pNode = head;
pNext = head->next;
pNode->next = NULL;
while(pNext!=NULL)
{
tmp = pNext->next;
pNext->next = pNode;
pNode = pNext;
pNext = tmp;
}
return pNode;
}
};
结果:8ms,Your runtime beats 25.35% of cppsubmissions.
2、另一种解法
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* pre = NULL;
while (head) {
ListNode* next = head -> next;
head -> next = pre;
pre = head;
head = next;
}
return pre;
}
};
3、递归版本
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (!head || !(head -> next)) return head;
ListNode* node = reverseList(head -> next);
head -> next -> next = head;
head -> next = NULL;
return node;
}
};
结果:12ms,Your runtime beats 4.90% of cppsubmissions.递归比迭代稍慢