203.移除链表元素
题目链接/文章讲解/视频讲解::https://programmercarl.com/0203.%E7%A7%BB%E9%99%A4%E9%93%BE%E8%A1%A8%E5%85%83%E7%B4%A0.html
思路 很简单的移除链表元素 遍历一下 用个虚拟头结点放头前面然后遍历如果是就跳过 不是就正常遍历
func removeElements(head *ListNode, val int) *ListNode {
dummyHead:=&ListNode{}
dummyHead.Next = head
cur :=dummyHead
for cur!=nil &&cur.Next!=nil{
if cur.Next.Val ==val {
cur.Next=cur.Next.Next
}else {
cur=cur.Next
}
}
return dummyHead.Next
}
707.设计链表
题目链接/文章讲解/视频讲解:https://programmercarl.com/0707.%E8%AE%BE%E8%AE%A1%E9%93%BE%E8%A1%A8.html
1.单链表解法
思路:单链表稍微好写一点,但是写的时候还是漏洞百出得看着写 ,真绕人啊 不过还是有点思路了
type Node struct{
Val int
Next *Node
}
type MyLinkedList struct {
dummyHead *Node
size int
}
func Constructor() MyLinkedList {
return MyLinkedList{&Node{},-1}
}
func (this *MyLinkedList) Get(index int) int {
if index < 0 || index > this.size{
return -1
}
cur := this.dummyHead
for i := 0; i <= index; i++ {
cur=cur.Next
}
return cur.Val
}
func (this *MyLinkedList) AddAtHead(val int) {
newNode:=&Node{val,this.dummyHead.Next}
this.dummyHead.Next = newNode
this.size++
}
func (this *MyLinkedList) AddAtTail(val int) {
newNode:=&Node{val,nil}
this.size++
cur:=this.dummyHead
for cur.Next!=nil{
cur=cur.Next
}
cur.Next = newNode
}
func (this *MyLinkedList) AddAtIndex(index int, val int) {
if index<=0{
this.AddAtHead(val)
}else if index==this.size+1{
this.AddAtTail(val)
}else if index>this.size+1{
return
}else{
this.size++
cur:=this.dummyHead
for i := 0; i < index; i++ {
cur=cur.Next
}
newNode:= &Node{val,cur.Next}
cur.Next = newNode
}
}
func (this *MyLinkedList) DeleteAtIndex(index int) {
if index<0 || index >this.size{
return
}
this.size--
var prev *Node
cur:=this.dummyHead
for i := 0; i <= index; i++ {
prev = cur
cur = cur.Next
}
prev.Next = cur.Next
}
2.循环链表
思路 循环链表 还是得画个图才行,这个就不用size 只需要判断cur是不是和dummy相等就知道是不是
type Node struct{
Val int
Next *Node
Prev *Node
}
type MyLinkedList struct {
dummy *Node
}
func Constructor() MyLinkedList {
rear:= &Node{
Val : -1,
Next : nil,
Prev : nil,
}
rear.Next = rear
rear.Prev = rear
return MyLinkedList{rear}
}
func (this *MyLinkedList) Get(index int) int {
head:= this.dummy.Next
for head!=this.dummy&&index>0{
index--
head=head.Next
}
if 0!=index{
return -1
}
return head.Val
}
func (this *MyLinkedList) AddAtHead(val int) {
dummy:=this.dummy
node:=&Node{
Val :val,
Next : dummy.Next,
Prev : dummy,
}
dummy.Next.Prev = node
dummy.Next = node
}
func (this *MyLinkedList) AddAtTail(val int) {
dummy:=this.dummy
rear := &Node{
Val:val,
Next: dummy,
Prev:dummy.Prev,
}
dummy.Prev.Next = rear
dummy.Prev = rear
}
func (this *MyLinkedList) AddAtIndex(index int, val int) {
head:=this.dummy.Next
for head!=this.dummy &&index>0{
head=head.Next
index--
}
if index>0{
return
}
node:=&Node{
Val:val,
Next:head,
Prev:head.Prev,
}
head.Prev.Next = node
head.Prev =node
}
func (this *MyLinkedList) DeleteAtIndex(index int) {
//链表为空
if this.dummy.Next == this.dummy{
return
}
head:=this.dummy.Next
for head.Next!=this.dummy&&index>0{
head =head.Next
index--
}
if index==0{
head.Prev.Next = head.Next
head.Next.Prev = head.Prev
}
}
206.反转链表
题目链接/文章讲解/视频讲解:https://programmercarl.com/0206.%E7%BF%BB%E8%BD%AC%E9%93%BE%E8%A1%A8.html
思路:这个题目之前跟着labuladong的那个思路写过但是那个思路挺难懂的 ,
这个双指针的话就很好理解, 先记录下个节点的位置,然后改指针朝向就行
递归的版本也是一个双指针的版本简化的
//双指针
func reverseList(head *ListNode) *ListNode {
var Prev *ListNode
cur := head
for cur!=nil{
next:=cur.Next//记录下一个节点的值
cur.Next=Prev//置空
Prev = cur//将prev置位cur上 这时 指向 5->4 5<-4
cur = next //向下挪
}
return Prev
}
//递归
func reverseList(head *ListNode) *ListNode {
return help(nil,head)
}
func help(prev,head *ListNode) *ListNode{
if head==nil{
return prev
}
next:=head.Next
head.Next = prev
// prev = head
// head = next
//这两步 直接放到了help递归去了 help的参数是 prev,head 放入相应的位置就等于赋值了
return help(head,next)
}
总结
今天这几题做的时间挺长的,链表还是不太熟悉,什么时候用虚拟头结点,判断临界值一系列的都不是很熟悉