LeetCode刷题日记精选例题-双指针经典问题总结
Posted 温文艾尔
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode刷题日记精选例题-双指针经典问题总结相关的知识,希望对你有一定的参考价值。
一、移除数组元素
public static int removeElement(int[] nums,int val)
int slowIndex;
int fastIndex = 0;
for (slowIndex = 0;fastIndex<nums.length;fastIndex++)
if (nums[fastIndex]!=val)
nums[slowIndex++]=nums[fastIndex];
return slowIndex;
二、反转字符串
public static void reverseString(char[] s)
for (int i=0,j=s.length-1;i<s.length/2;i++,j--)
char c = s[i];
s[i]=s[j];
s[j]=c;
三、替换空格(剑指Offer)
public static String replaceSpace(String s)
if (s.length()==0)
return null;
StringBuilder ss = new StringBuilder();
for (int i=0;i<s.length();i++)
if (s.charAt(i)==' ')
ss.append(" ");
int left = s.length();
s+=new String(ss);
int right = s.length();
char[] chars = s.toCharArray();
while (left>=0)
if (chars[right]==' ')
chars[right--]='0';
chars[right--]='2';
chars[right]='%';
else
chars[right]=chars[left];
left--;
right--;
return String.valueOf(chars);
四、翻转字符串里的单词
public static String reverseWords(String s)
if (s==null)
return null;
String trim = s.trim();
StringBuilder str = new StringBuilder();
int left = trim.length()-1;
int right = trim.length()-1;
while (left>=0)
if (left>0&&' '==trim.charAt(left-1))
str.append(trim.substring(left,right+1));
while (' '==trim.charAt(left-1))
left--;
else if (' '==trim.charAt(left))
str.append(" ");
left--;
right=left;
else if (left==0)
str.append(trim.substring(left,right+1));
left--;
else
left--;
return new String(str);
五、翻转链表
public static ListNode reverseList(ListNode head)
if (head==null)
return null;
ListNode cur = head;
ListNode temp;
ListNode resverNode = new ListNode();
ListNode pre = new ListNode();
pre.next = head;
while (cur!=null)
temp = cur.next;
cur.next = resverNode.next;
resverNode.next=cur;
cur=temp;
pre.next = resverNode.next;
return pre.next;
六、删除链表的倒数第n个结点
双指针解题 设立两个指针,第一个指针向前移动n步,随后两个指针同时移动,当第一个指针到达末尾时,第二个指针刚好到达第n个位置
public ListNode removeNthFromEnd(ListNode head, int n)
ListNode cur = head;
ListNode pre = new ListNode(-1);
pre.next = cur;
ListNode fast = head;
for (int i=0;i<n;i++)
fast = fast.next;
ListNode p = new ListNode();
while (fast.next!=null)
p=cur;
cur = cur.next;
fast = fast.next;
//此时cur为要删除的位置,pre为要删除位置的前一个位置
p.next = cur.next;
return pre.next;
七、链表相交
public ListNode getIntersectionNode(ListNode headA, ListNode headB)
int lengthA = getLinkedLength(headA);
int lengthB = getLinkedLength(headB);
ListNode curA = headA;
ListNode curB = headB;
if (lengthB>lengthA)
int temp = lengthA;
lengthA = lengthB;
lengthB = temp;
ListNode p = curA;
curA = curB;
curB = p;
int L = lengthA-lengthB;
for (int i=0;i<L;i++)
curA = curA.next;
while (curA!=null)
if (curA==curB)
return curA;
curA = curA.next;
curB = curB.next;
return null;
private int getLinkedLength(ListNode head)
int length = 0;
ListNode cur = head;
while (cur!=null)
length++;
cur=cur.next;
return length;
八、环形链表
public ListNode detectCycle(ListNode head)
if (head==null)
return null;
ListNode fast = head;
ListNode slow = head;
//快指针走2步,慢指针走1步
while (fast!=null&&fast.next!=null)
fast = fast.next.next;
slow = slow.next;
if (fast==slow)
ListNode node = head;
while (node!=fast)
fast = fast.next;
node = node.next;
return node;
return null;
九、三数之和
public static List<List<Integer>> threeSum(int[] nums)
Arrays.sort(nums);
List<List<Integer>> list = new ArrayList<>();
//-4,-1,-1,0,1,2
for (int i=0;i<nums.length-2;i++)
int left = i+1;
int right = nums.length-1;
while (left<right)
int value = 0-(nums[i]+nums[left]+nums[right]);
if (value==0)
list.add(Arrays.asList(nums[i],nums[left],nums[right]));
while (right>left&&nums[right]==nums[right-1]) right--;
while (right>left&&nums[left]==nums[left+1]) left++;
right--;
left++;
else if (value>0)
right--;
else
left++;
return list;
十、四数之和
public static List<List<Integer>> fourSum(int[] nums, int target)
Arrays.sort(nums);
List<List<Integer>> list = new ArrayList<>();
if (nums==null||nums.length<4)
return list;
for (int i=0;i<nums.length-3;i++)
if (i>0&&nums[i]==nums[i-1])
continue;
for (int j=i+1;j<nums.length-2;j++)
if (j-1>i&&nums[j]==nums[j-1])
continue;
int left = j+1;
int right = nums.length-1;
while (left<right)
int value =(nums[i]+nums[j]+nums[left]+nums[right]);
if (value>target)
right--;
else if (value<target)
left++;
else
list.add(Arrays.asList(nums[i],nums[j],nums[left],nums[right]));
while (right>left&&nums[right]==nums[right-1]) right--;
while (right>left&&nums[left]==nums[left+1]) left++;
right--;
left++;
return list;
以上是关于LeetCode刷题日记精选例题-双指针经典问题总结的主要内容,如果未能解决你的问题,请参考以下文章