不定时更新—喜欢的可以先收藏一下
- 环形链表
思路:采用快慢指针思维,设置一个快指针,一个慢指针,快指针一次走两步,慢指针一次走一步,如果有环存在,快慢指针总会相遇,如果没环,快指针会先指向空节点。
public class Solution {
public boolean hasCycle(ListNode head) {
if(head==null){
return false;
}
ListNode p = head;
ListNode q = head.next;
while(p!=q&&q!=null&&q.next!=null){
p = p.next;
q = q.next.next;
}
return q!=null&&q.next!=null;
}
}
- 环形链表 II
思路: 寻找环的起始点:因为快指针一直在追慢指针,当慢指针走到环起点的时候,快指针已经哦足了慢指针的2倍,当快慢指针在环中相遇的时候,相遇位置到环起点的距离和链表头节点到环起点的距离相同,让一个节点返回头节点,两个节点一起走,相遇位置就是环起点
这里要注意,在我们写的代码中,快节点出发时比慢节点早一个节点,所以实际再环中相遇的位置比设想的早了一次,所以环中的那个节点要再往前走一次,才能保证两个会相遇。
-------画图可以方便理解
public class Solution {
public ListNode detectCycle(ListNode head) {
if(head == null){
return null;
}
ListNode q = head.next;
ListNode p = head;
while(p!=q&&q!=null&&q.next!=null){
p = p.next;
q = q.next.next;
}
if(q!=null&&q.next!=null){
p=p.next;
q = head;
while(p!=q){
p = p.next;
q = q.next;
}
return p;
}else{
return null;
}
}
}
202.快乐数 思路 :虽然不是链表,但是用到了上面的快慢指针思想。因为如果到不了1,就意味着再某一段数字内陷入了循环状态,陷入了循环状态就代表有环。
class Solution {
public boolean isHappy(int n) {
int p = n;
int q = n;
do{
p = getNum(p);
q = getNum(getNum(q));
}while(q!=p&&q!=1);
return q==1;
}
public int getNum(int i){
int z = 0;
while(i!=0){
z = z + (i%10)*(i%10);
i = i / 10;
}
return z;
}
}
206.反转链表 思路: (1)设立三个链表节点(迭代的方法): cur的next = pre,pre再等于cur,cur=next,next = cur.next pre->反转以后链表的头节点 cur->未反转链表的头节点 next->未反转链表的头节点的下一位
class Solution {
public ListNode reverseList(ListNode head) {
if(head == null||head.next ==null)
return head;
ListNode pre = null;
ListNode cur = head;
ListNode next = cur.next;
while(cur!=null){
cur.next = pre;
pre = cur;
cur = next;
if(next!=null)
next = next.next;
}
return pre;
}
}
(2)使用递归的方法 :将该节点插入到该节点后面的所有节点的反转的末尾 leetcode:
class Solution {
public ListNode reverseList(ListNode head) {
if(head == null||head.next ==null)
return head;
ListNode tail = head.next;
ListNode re = reverseList(head.next);
head.next = tail.next;
tail.next = head;
return re;
}
}
- 反转链表 II
思路:先找到m的前一个位置,然后反转该位之后的前n个链表。 用到了虚拟头节点(建立一个节点,指向链表的头节点)
|