Algoritmo de punteros duales, a veces te sientes muy listo, resuelves muchos problemas, es necesario resumir, en primer lugar el de dos punteros es un concepto muy amplio, que es un recorrido similar i 和 j
pero la diferencia es que los dos punteros se mueve en el Al mismo tiempo, es decir, no aporta la complejidad de O(N)
a a O(N*N)
, por lo que es elogiado por muchos líderes de algoritmos, por lo que con base en esta inducción, resumimos las soluciones y rutinas comunes de punteros duales.
1. Introducción al tipo de pregunta
Hay tres tipos de preguntas, que son las siguientes:
Punteros rápidos y lentos (presione los dos punteros que no están sincronizados antes y después)
Punteros dobles delanteros y traseros (uno en la cabeza, uno en la cola, acercándose al centro)
Punteros de intervalo fijo (dos punteros con un espaciado de i, i + k)
Como se mencionó anteriormente, estos tres punteros se pueden completar atravesando la matriz una vez, y su complejidad de tiempo es menor o igual a O(N)
, y la complejidad de espacio se O(1)
debe a que solo se almacenan dos punteros.
2. Tipos de preguntas habituales
2.1 Punteros rápidos y lentos
Una pregunta bastante clásica:
- Determine si la lista vinculada tiene un anillo
A través de los dos punteros a diferentes ritmos, muévase uno tras otro hasta que los punteros coincidan
https://leetcode.com/problems/linked-list-cycle/description , el fragmento de código es el siguiente:
public boolean hasCycle(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (slow != null && fast != null) {
ListNode n = fast.next;
fast = n == null ? null : n.next;
if (slow == fast) {
return true;
}
slow = slow.next;
}
return false;
}
- Busque números plurales repetidos y encuentre un entero repetido de la matriz: https://leetcode-cn.com/problems/find-the-duplicate-number/
El código se resuelve de la siguiente manera:
public int findDuplicate(int[] nums) {
// 将其看成是一个循环的链表,快慢指针循环
int index1 = 0;
int index2 = 0;
do
{
index1 = nums[index1];
index2 = nums[index2];
index2 = nums[index2];
}while (nums[index1] != nums[index2]);
index1 = 0;
// 找出在哪个位置为起始点,可证必定在圆圈起点相遇
while(index1 != index2){
index1 = nums[index1];
index2 = nums[index2];
}
return index1;
}
2.2 Punteros de punto final delantero y trasero
- Búsqueda binaria
La búsqueda binaria es un tipo de pregunta típico con punteros delanteros y traseros. El código es el siguiente:
public static int binarySearch(int[] array, int targetElement) {
int leftIndex = 0, rightIndex = array.length - 1, middleIndex = (leftIndex + rightIndex) / 2;
while(leftIndex <= rightIndex) {
int middleElement = array[middleIndex];
if(targetElement < middleElement) {
rightIndex = middleIndex - 1;
}else if(targetElement > middleElement) {
leftIndex = middleIndex + 1;
}else {
return middleIndex;
}
middleIndex = (leftIndex + rightIndex) / 2;
}
return -1;
}
2.3 Punteros a intervalos fijos
- Encuentre el punto medio de la lista vinculada https://leetcode-cn.com/problems/middle-of-the-linked-list/
// 快指针q每次走2步,慢指针p每次走1步,当q走到末尾时p正好走到中间。
class Solution {
public ListNode middleNode(ListNode head) {
ListNode p = head, q = head;
while (q != null && q.next != null) {
q = q.next.next;
p = p.next;
}
return p;
}
}
- Encuentre el elemento kth en la parte inferior de la lista vinculada https://leetcode-cn.com/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/
// 快慢指针,先让快指针走k步,然后两个指针同步走,当快指针走到头时,慢指针就是链表倒数第k个节点。
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode frontNode = head, behindNode = head;
while (frontNode != null && k > 0) {
frontNode = frontNode.next;
k--;
}
while (frontNode != null) {
frontNode = frontNode.next;
behindNode = behindNode.next;
}
return behindNode;
}
3. Resumen de la plantilla
Después de leer los tres códigos, ¿crees que es muy simple? Aquí tienes un resumen de las tres plantillas de código de doble puntero
// 1.快慢指针
l = 0
r = 0
while 没有遍历完
if 一定条件
l += 1
r += 1
return 合适的值
//2. 左右端点指针
l = 0
r = n - 1
while l < r
if 找到了
return 找到的值
if 一定条件1
l += 1
else if 一定条件2
r -= 1
return 没找到
//3. 固定间距指针
l = 0
r = k
while 没有遍历完
自定义逻辑
l += 1
r += 1
return 合适的值
Wu Xie, Xiao San Ye, un pequeño novato en segundo plano, big data e inteligencia artificial. Presta atención a más