1.双指针
双指针问题主要有 数组对撞,快慢指针两个问题
双指针法充分使用了数组有序这一特征;
双指针指的是在遍历对象的过程中,不是普通的使用单个指针进行访问,而是使用两个相同方向(快慢指针)或者相反方向(对撞指针)的指针进行扫描,从而达到相应的目的。
详细参考知乎文章
1.1 数组对撞
对撞数组适用于有序数组,也就是说当你遇到题目给定有序数组时,应该第一时间想到用对撞指针解题;
例题:以LeetCode 881救生艇问题为例
class Solution {
public:
int numRescueBoats(vector<int>& people, int limit) {
sort(people.begin(), people.end());
int res = 0;
vector<int>::iterator pb = people.begin(),pe = people.end()-1;
while(pb<=pe)
{
if( *pb + *pe <= limit)
{
pb++;
}
pe--;
res++;
}
return res;
}
};
1.2 快慢指针
主要用于检查是否有环,检查链表是不是相交,文章第四部分
好像一个环形跑道上有一快一慢两个运动员赛跑,如果时间足够长,跑地快的运动员一定会赶上慢的运动员。
class Solution {
public:
bool hasCycle(ListNode *head) {
ListNode *Slow = head,*Fast = head;
while( Fast != NULL&&Slow !=NULL&&Fast ->next !=NULL) //+判断 Fast ->next ==NULL 时 Fast ->next ->next会报错
{
Slow = Slow ->next;
Fast = Fast ->next ->next;
if(Fast == Slow)
return true;
}
return false;
}
};
leetcode题解还提供一种哈希表的解法:
C++貌似没有哈希表只有map?没找到C++哈希表内容;
学习java哈希表一下:
public boolean hasCycle(ListNode head) {
Set<ListNode> nodesSeen = new HashSet<>();
while (head != null) {
if (nodesSeen.contains(head)) {
return true;
} else {
nodesSeen.add(head);
}
head = head.next;
}
return false;
}