计算机在1s、2s内可运行<=10^8次
前为给定的大小,后均为时间复杂度↓
n <= 30,指数级别:考虑 dfs+剪枝
n = 100 => n^3:floyd算法
n = 1000 => n^2:n^2logn,地杰斯特拉算法
n = 10000 => n * sqrt(n):块状链表
n = 100000 => nlogn:排序算法、线段树、树状数组、set/map、heap、heap+dijkstra、spfa、求凸包、求半平面交、二分
n = 1000000 => O(n)、nlogn:hash、双指针扫描、kmp、AC自动机,
常数比较小的nlogn算法:排序、树状数组、heap、dijkstra、spfa
n = 10000000 => O(n):双指针扫描、kmp、AC自动机、线性筛数组
n = 10^9 => O(sqrt(n))
n = 10^18 =>O(logn):求最大公约数、
链表专题
题目1:给定一个有序链表,要求删除链表中的重复元素,使得原链表的元素仅出现一次。
链表结点的定义如下:
struct ListNode{
int val;
ListNode *next;
ListNode(int x) : val(x),next(NULL) {}
}
样例1:1->1->2,则输出为1->2
样例2:1->1->2->3->3,则输出1->2->3
算法:线性扫描 O(n),从前往后扫描整个链表,如果一个结点和其后继结点相同,则直接删除后继结点,否则指针移动到后继结点。
class Solution{
public:
ListNode* deleteDuplicates(ListNode* head){
if(!head) return nullptr;
ListNode *p = head;
while(p->next){
if(p->next->val == p->val) p->next = p->next->next;
else p = p->next;
}
return head;
}
}
题目2:给出两个排好序的单向链表,返回合并排序后新的单向链表。
样例:1->2->4,1->3->4
返回:1->1->2->3->4->4
算法:线性合并 O(n)
class Solution{
public:
ListNode* mergeTwoLists(ListNode* l1,ListNode *l2){
ListNode *dummy = new ListNode(0);
ListNode *cur = dummy;
while(l1!=NULL && l2!=NULL){
if(l1->val < l2->val){
cur->next = l1;
l1 = l1->next;
}
else{
cur->next = l2;
l2 = l2->next;
}
cur = cur->next;
}
cur->next = (l1!=NULL?l1:l2);
return dummy->next;
}
}
题目3:给定一个链表,如果存在环,则返回环的入口,否则返回null。注:不能修改链表。是否只是用额外O(1)的空间?
算法:指针扫描 O(n),构造两个指针first和second,first每走一步,second走两步,如果过程中,second走到null,则不存在环,否则当first和second相遇时,让first返回起点,second待在相遇点不动,然后两指针每次分别走一步,当相遇时,该点就是环的入口。
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode *fast,*slow;
fast = slow = head;
while(fast!=nullptr && fast->next!=nullptr){
fast = fast->next->next;
slow = slow->next;
if(slow == fast){
ListNode *node1 = head;
ListNode *node2 = fast;
while(node1!=node2){
node1 = node1->next;
node2 = node2->next;
}
return node1;
}
}
return NULL;
}
};
题目4:给定一个单链表,请使用O(nlogn)的时间复杂度和额外O(1)的空间复杂度对其进行排序。
样例1:
输入:4->2->1->3
输出:1->2->3->4
样例2:
输入:-1->5->3->4->0
输出:-1->0->3->4->5
算法:归并排序,时间O(nlogn),自顶向下递归形式的归并排序,由于递归需要使用系统栈,递归最大深度为logn,所以需要额外O(logn)的空间。所以我们需要使用自底向上非递归形式的归并排序算法。