分类
1:两个指针从不同位置出发:一个从始端开始,另一个从末端开始;
2:两个指针以不同速度移动:一个指针快一些,另一个指针慢一些。
1 :快慢指针
*主要解决链表中的问题,快指针在前,慢指针在后,巧妙解决问题,降低时间复杂度
1、判定链表中是否含有环
思路:
如果不含有环,跑得快的那个指针最终会遇到 null,说明链表不含环;如果含有环,快指针最终会超慢指针一圈,和慢指针相遇,说明链表含有环。
boolean hasCycle(ListNode head) {
ListNode fast, slow;
fast = slow = head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow) return true;
}
return false;
}
2 :删除倒数第n个结点
思路
1 先让快指针走n步
2当快指针的next为NULL 慢指针的next则为删除的结点
struct ListNode* removeNthFromEnd(struct ListNode* head, int n){
struct ListNode *fast = head ,*slow = head ;
while( n-- > 0)
fast = fast->next;
while(fast && fast ->next) //判断fast 防止访问空指针的next
{
fast = fast->next;
slow = slow->next;
}
if(fast == NULL) // 删头节点
head = head->next;
else
slow->next = slow->next->next;
return head;
}
** 3 :相交链表**
思路:
1 两个指针分别指向不同的链表
2 当2个链表都不为空 则分别依
次遍历两个链表
3 当两个结点不相等时,均更新到下一节点
如果指针 p1 为空,则将指针p1 移到链表 p2 的头节点;如果指针 p2 为空,则将指针 p2 移到链表 p1 的头节点。
4 当指向同一结点或为空时,返回该结点
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
if(headA == NULL || headB == NULL)
return NULL;
struct ListNode *p1 = headA , *p2 = headB;
while(p1 != p2)
{
p1 = p1 == NULL ? headB : p1->next;
p2 = p2 == NULL ? headA : p2->next;
}
return p1;
}
2 :左右指针
主要解决数组(或者字符串)中的问题,一个在首,一个在尾,判断是否满足条件
1 二分查找:
int binarySearch(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while(left <= right) {
int mid = (right + left) / 2;
if (nums[mid] == target)
return mid;
else if (nums[mid] < target)
left = mid + 1;
else if (nums[mid] > target)
right = mid - 1;
}
}
2 字符串 ,数组是否回文
3 滑动窗口