使用双链表实现
type Node4 struct {
Next *Node4
Prev *Node4
Val int
}
type MyLinkedList struct {
head *Node4 // 头结点
tail *Node4 // 尾结点
size int // 链表的长度
}
/** Initialize your data structure here. */
func Constructor3() MyLinkedList {
return MyLinkedList{}
}
/** Get the value of the index-th node in the linked list. If the index is invalid, return -1. */
func (this *MyLinkedList) Get(index int) int {
// index无效
if this.size == 0 || index < 0 || index >= this.size {
return -1
}
// index为头尾节点
if index == 0 {
return this.head.Val
}
if index == this.size-1 {
return this.tail.Val
}
// 下面选择更快的遍历方向, 查看index在偏头部还是偏尾部
cur := this.head
count := 0
for cur != nil {
if count == index {
break
}
count++
cur = cur.Next
}
return cur.Val
}
/** Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list. */
func (this *MyLinkedList) AddAtHead(val int) {
node := &Node4{Val: val}
if this.head != nil {
node.Next = this.head
this.head.Prev = node
this.head = node
} else {
this.head = node
this.tail = this.head
}
this.size++
}
/** Append a node of value val to the last element of the linked list. */
func (this *MyLinkedList) AddAtTail(val int) {
node := &Node4{Val: val}
if this.tail != nil {
node.Prev = this.tail
this.tail.Next = node
this.tail = node
} else {
this.tail = node
this.head = this.tail
}
this.size++
}
/** Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted. */
func (this *MyLinkedList) AddAtIndex(index int, val int) {
if index > this.size {
return
}
if index <= 0 {
this.AddAtHead(val)
return
}
if index == this.size {
this.AddAtTail(val)
return
}
cur := this.head
count := 0
for cur != nil && count < index {
count++
cur = cur.Next
}
// 在当前节点cur的前面插入
this.size++
node := &Node4{Val: val, Next: cur, Prev: cur.Prev}
cur.Prev.Next = node
cur.Prev = node
}
/** Delete the index-th node in the linked list, if the index is valid. */
func (this *MyLinkedList) DeleteAtIndex(index int) {
// 如果索引无效 || 链表为空
if this.size == 0 || index < 0 || index >= this.size {
return
}
if index == 0 {
// 如果删除的是头结点
this.head = this.head.Next
} else if index == this.size-1 {
// 如果删除的是尾结点
this.tail = this.tail.Prev
} else {
cur := this.head
count := 0
for cur != nil && count < index {
count++
cur = cur.Next
}
// 找到要删除的节点cur了
cur.Next.Prev = cur.Prev
cur.Prev.Next = cur.Next
}
this.size--
}
二维切片 四个for循环
滑动窗口,need去判断是不是t元素
func minWindow(s string,t string) string {
need := map[byte]int{}
//有用的t在哈希表里值大于0
for i := 0; i < len(t); i++ {
need[t[i]]++
}
//need[c]正负,只是用来判断是不是t的元素
// l: 滑动窗口左边界
// r: 滑动窗口右边界
//count: 当次遍历中还需要几个字符才能够满足包含t中所有字符的条件,最大也就是t的长度
// start: 如果有效更新滑动窗口,记录这个窗口的起始位置,方便后续找子串用
l,r,count,size,start := 0,0,len(t),math.MaxInt32,0
for ;r<len(s);r++{
c := s[r]
if need[c] > 0{ //说明这个字符串是需要覆盖的元素,把它覆盖的时候,要把need减去,count-1
count--
}
//不是话就--让他为负数
need[c]--
//判断count情况,如果count=0了,说明啥?笨蛋 说明t都包含在里面了啊;那么就要移动l
if count == 0{
for l<r && need[s[l]] < 0 {
//count==0表示这个框里包含了t,那么判断l的位置是不是t元素,通过什么判断呢,通过need正负,若果小于0那么他就不是tt元素,直接删除
//小于0就是咱们不需要的东西 一个是多余的t元素,一个是不在t里的元素 所以就移动左边沿
//左移动 要更新维护need
need[s[l]]++
l++
}
//这就代表l位置是t元素,l移动之前,先算一下大小
if r-l+1<size{
size = r-l+1
start = l
}
//先将l位置的字符计数重新加1
need[s[l]]++
l++
count++
}
}
if size == math.MaxInt32{
return ""
}else {
return s[start:start+size]
}
}