力扣刷题第十二天--链表篇

前言

还是静不下来,浮躁,总是受外界影响。。。

内容

一、相交链表

160.相交链表

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。

图示两个链表在节点 c1 开始相交

题目数据 保证 整个链式结构中不存在环。

注意,函数返回结果后,链表必须 保持其原始结构 。

自定义评测:

评测系统 的输入如下(你设计的程序 不适用 此输入):

  • intersectVal - 相交的起始节点的值。如果不存在相交节点,这一值为 0
  • listA - 第一个链表
  • listB - 第二个链表
  • skipA - 在 listA 中(从头节点开始)跳到交叉节点的节点数
  • skipB - 在 listB 中(从头节点开始)跳到交叉节点的节点数

评测系统将根据这些输入创建链式数据结构,并将两个头节点 headA 和 headB 传递给你的程序。如果程序能够正确返回相交节点,那么你的解决方案将被 视作正确答案 。

快慢指针

注意curA和headA,使用不当会出错误

func getIntersectionNode(headA, headB *ListNode) *ListNode {
    countA,countB:=0,0
 curA:=headA
  curB:=headB
//原因是在循环中更新headA和headB的值时,它们被更新为nil,导致循环提前结束。而在后面的代码中,尝试访问headA和headB的值,这会导致空指针错误
   for ;curA!=nil;curA=curA.Next{//curA不能为headA 
     countA++
  }
    for ;curB!=nil;curB=curB.Next{
     countB++
  }
  var fast,slow *ListNode
  var step int
  if countA>countB{
     step=countA-countB
     fast=headA//同样的 此时也不能为curA
     slow=headB
  }else{
      step=countB-countA
      fast=headB
      slow=headA
  }
  for i:=0; i < step; i++ {
        fast = fast.Next //不然 这里会出错
    }
for fast!=slow{
    fast=fast.Next
    slow=slow.Next
}
return fast
}
双指针

双指针 好神奇 pA遍历完headA去headB pB遍历完headB去headA 两指针相遇 返回相遇时的结点即为相交结点

时间复杂度:O(m+n)  空间复杂度:O(1)

func getIntersectionNode(headA, headB *ListNode) *ListNode {
    if headA==nil||headB==nil{
        return nil
    }
    pA,pB:=headA,headB
   for pA!=pB{
     if pA!=nil{
         pA=pA.Next
     }else{
         pA=headB//headB不是pB
     }
       if pB!=nil{
           pB=pB.Next
       }else{
           pB=headA
       }

   }
    return pA
}
哈希表 

哈希表 确实没想到

//时间复杂度:O(m+n)

//空间复杂度:O(m),其中 m是链表 headA的长度。需要使用哈希集合存储链表 headA中的全部节点。

func getIntersectionNode(headA, headB *ListNode) *ListNode {
   arr:=map[*ListNode]bool{}
   for temp:=headA;temp!=nil;temp=temp.Next{
       arr[temp]=true
   }
   for temp:=headB;temp!=nil;temp=temp.Next{
       if arr[temp]{
           return temp
       }
   }
   return nil
}
 二、环形链表

142.环形链表Ⅱ

给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

不允许修改 链表。

哈希表

同题141 哈希表存储访问过的结点,再次访问到的结点即为入环的第一个节点

func detectCycle(head *ListNode) *ListNode {
    hashTable:=map[*ListNode]struct{}{}
    for head!=nil{
      if _,ok:=hashTable[head];ok{
          return head
      }
      hashTable[head]=struct{}{}
      head=head.Next
    }
return nil
}
快慢指针

空间复杂度:O(1) 我们只使用了 slow,fast,ptr 三个指针

func detectCycle(head *ListNode) *ListNode {
   fast,slow:=head,head
   for fast!=nil{
       slow=slow.Next
       if fast.Next==nil{
           return nil
       }
       fast=fast.Next.Next
       if fast==slow{
           p:=head
          for p!=slow{
              p=p.Next
              slow=slow.Next
          }
          return p
       }
   }
   return nil
}
三、旋转链表

 61.旋转链表

给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。

思路:闭合为环
func rotateRight(head *ListNode, k int) *ListNode {
    if head==nil||head.Next==nil||k==0{
        return head
    }
    count:=0
    cur:=head
    for cur.Next!=nil{
        count++
       cur=cur.Next
    }
    // 因为上面判断的是当前节点的下一个节点何时为nil,也即是少计算了一个尾结点,所以count++
    count++
    cur.Next=head// 将尾巴指向头部
    cur=head// 重新指向头部
   k=k%count
  for i:=1;i<count-k;i++{
      cur=cur.Next
  }
  result:=cur.Next//result 就是新的头节点
  cur.Next=nil//将 cur.Next 设为 nil,断开原本的连接
  return result
}

最后

应该要结束链表了,明天写个总结。

  • 10
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值