一 快慢指针
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 寻找链表的中点
快指针走两步,慢指针走一步,快指针为null则慢指针在中点
while (fast != null && fast.next != null){
fast = fast.next.next; slow = slow.next;
} // slow 就在中间位置
return slow;
3 寻找链表的倒数第 k 个元素
定义快慢指针,快指针先走k步
ListNode slow, fast;
slow = fast = head;
while (k-- > 0)
fast = fast.next;
while (fast != null) {
slow = slow.next;
fast = fast.next;
}
return slow
二 左右指针
左右指针在数组中实际是指两个索引值,⼀般初始化为 left = 0, right = nums.length - 1 。
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;
}
return -1;
}
2 反转数组
void reverse(int[] nums) {
int left = 0;
int right = nums.length - 1;
while (left < right) {
// swap(nums[left], nums[right])
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
left++; right--;
}
}
3 滑动窗口
双重while循环,外层right指针,内层left指针,外层动完内层从动
public int windon(int[] nums) {
//创建滑动窗口
Map<Character,Integer> map=new HashMap<Character,Integer>();
int max=0;
int ans=0;
//创建双指针
int right=0,left=0;
while(right<nums.length)
{
//增大窗口 右指针进行移动 并进行相应的业务逻辑
//right++;
while(条件){//如果满足题意 就要开始缩小窗口 左指针进行移动 并进进行业余数据的更新
//left++;
//更新最佳值
//ans=...;
}
return ans;
}
-
当不满足条件时,拓展有边界,当满足条件时缩短左边边界,最后得到一个解并暂存
-
循环第一步,又得到一个解,将其与第一个解相对比,得到优解并暂存,以此类推得到最优解