双指针
题目一
- 链表的中间结点
给定一个头结点为 head 的非空单链表,返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
解题思路
拿到题目开始,可能会有些摸不清头脑,不是就是查中间位置然后输出,直接就头指针加尾指针然后除2取整就行。不过用这样的方法实在是太费内存了。倘若用count来计数,需要用for循环,最后输出还是要for循环。不如换个思路想,既然是中间,那设置两个指针,分别一个走一次,另一个每次走2格,到达末尾的时候,一次走一格的不是恰好在中间吗?
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode middleNode(ListNode head) {
ListNode result = head;
while(head != null && head.next != null){
head = head.next.next;
result = result.next;
}
return result;
}
}
题目二
- 删除链表的倒数第 N 个结点
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
解题思路
同样也是要写双指针,我们通过让快指针先走n个,之后再让慢指针和快指针同时走,当快指针走到底的时候,慢指针的位置正好是要删除的位置。之后就跟链表赋值一样,让next指向next.next即可。
class Solution {
public void rotate(int[] nums, int k) {
int subnums[]=new int [k];
int result[]=new int [nums.length];
if(k>nums.length)
{
while(k>nums.length)
{
k=k-nums.length;
}
}
for(int i=0;i<k;i++)
{
subnums[k-1-i]=nums[nums.length-1-i];
}
for(int i=0;i<nums.length;i++)
{
if(i<k)
{
result[i]=subnums[i];
}
else
{
result[i]=nums[i-k];
}
}
for(int i=0;i<nums.length;i++)
{
nums[i]=result[i];
}
}
}