【7.6】算法复习一 链表

7.6

  • 1 翻转
function ReverseList(pHead)
{
    // write code here
    let cur = pHead
    let pre = null
    while(cur){
        [cur.next,pre,cur] = [pre,cur,cur.next]
    }
    return pre
}
  • 2 指定闭区间翻转
function reverse(head){
    let cur = head,pre = null
    while(cur){
        [cur.next,pre,cur] = [pre,cur,cur.next]
    }
    return [pre,head]
}
function reverseBetween( head ,  m ,  n ) {
    // write code here
    let origin={next:head}
    let left = origin,right = origin
    for(let i=0;i<m-1;i++){
        left = left.next
    }
    for(let j=0;j<n;j++){
        right = right.next
    }
    let save = right.next
    right.next = null
    let [start,end] = reverse(left.next)
    left.next = start
    end.next = save
    return origin.next
}
  • 3 k个一组翻转(不足k则保持原样)
function reverseKGroup( head ,  k ) {
    // write code here
    let cur = head,key = head
    let pre = null
    for(let i=0;i<k;i++){
        if(!key){
            return head
        }
        key = key.next
    }
    for(let j=0;j<k;j++){
        [cur.next,pre,cur] = [pre,cur,cur.next]
    }
    head.next = reverseKGroup(cur,k)
    return pre
}
  • 4 合并两个排序链表
function Merge(pHead1, pHead2)
{
    // write code here
    if(!pHead1||!pHead2) return pHead1||pHead2
    if(pHead1.val >= pHead2.val){
        pHead2.next = Merge(pHead1, pHead2.next)
        return pHead2
    }
    else{
        pHead1.next = Merge(pHead1.next, pHead2)
        return pHead1
    }
}
  • 5 合并k个排序链表【这个有点难 写归并】
function mergeKLists( lists ) {
    // write code here
    if(lists.length <2) return lists[0] || null
    return merge(lists,0,lists.length-1)
}
function merge(lists,l,r){
    if(l>r) return null
    if(l == r) return lists[l]
    let mid = (Math.floor((l+r)/2))
    return mergetwo(merge(lists,l,mid),merge(lists,mid+1,r))
}
function mergetwo(list1,list2){
    if(!list1||!list2) return list1||list2
    if(list1.val>=list2.val){
        list2.next = mergetwo(list1,list2.next)
        return list2
    }else{
        list1.next = mergetwo(list1.next,list2)
        return list1
    }
}
  • 6 判断链表中是否有环
function hasCycle( head ) {
    // write code here
    while(head){
        if(head.flag) return true
        head.flag = true
        head = head.next
    }
    return false
}
  • 7 链表中环的入口节点
function EntryNodeOfLoop(pHead)
{
    // write code here
    while(pHead){
        if(pHead.flag) return pHead
        pHead.flag = true
        pHead = pHead.next
    }
    return null
}
  • 8 链表中倒数最后k个节点
function FindKthToTail( pHead ,  k ) {
    // write code here
    let slow=pHead,fast=pHead
    for(let i=0;i<k;i++){
        if(!fast) return null
        fast = fast.next
    }
    while(fast){
        slow = slow.next
        fast = fast.next
    }
    return slow
}
  • 9 删除链表倒数第n个节点(题目保证n有效)
function removeNthFromEnd( head ,  n ) {
    // write code here
    let origin={next:head}
    let slow = origin,fast = origin
    for(let i=0;i<n;i++){
        fast = fast.next
    }
    while(fast.next){
        slow = slow.next
        fast = fast.next
    }
    slow.next = slow.next.next
    return origin.next
}
  • 10 两个链表的第一个公共节点 【这个解法蛮特别的 不太好想 追及问题】
function FindFirstCommonNode(pHead1, pHead2)
{
    // write code here
    let p1 = pHead1,p2 = pHead2
    while(p1 !== p2){
        p1 = p1 == null?pHead2:p1.next
        p2 = p2 == null?pHead1:p2.next
    }
    return p1
}
  • 11 经典链表相加 加法竖式型【背下来】
function reverse(cur){
    let pre = null
    while(cur){
        [cur.next,pre,cur] = [pre,cur,cur.next]
    }
    return pre
}
function addInList( head1 ,  head2 ) {
    // write code here
    let p1 = reverse(head1)
    let p2 = reverse(head2)
    let res = null
    let carry = 0
    while(p1 || p2){
        let x1= p1 == null ? 0:p1.val
        let x2= p2 == null ? 0:p2.val
        let sum = x1+x2+carry
        carry = Math.floor(sum/10)
        let node = new ListNode(sum%10)
        node.next = res
        res = node
        p1 = p1 == null?null:p1.next
        p2 = p2 == null?null:p2.next
    }
    if(carry){
        let node = new ListNode(carry)
        node.next = res
        res = node
    }
    return res
}
  • 12 对无序单链表升序排序(nlogn) 【复习一下快排】
function sortInList( head ) {
    // write code here
    let arr = []
    let cur = head
    while(cur){
        arr.push(cur.val)
        cur = cur.next
    }
    function quicksort(arr){
        if(arr.length < 2) return arr
        let pivot = arr[0]
        let left  = []
        let right = []
        for(let i=1;i<arr.length;i++){
            arr[i] >= pivot ? right.push(arr[i]) : left.push(arr[i])
        }
        return [...quicksort(left),pivot,...quicksort(right)]
    }
    let arr2 = quicksort(arr)
    cur = head
    for(let j=0;j<arr2.length;j++){
        cur.val = arr2[j]
        cur = cur.next
    }
    return head
}
  • 13 判断一个链表是否为回文结构
function isPail( head ) {
    // write code here
    let arr = []
    let arr2 = []
    while(head){
        arr.push(head.val)
        arr2.push(head.val)
        head = head.next
    }
    arr.reverse()
    for(let i=0;i<arr.length;i++){
        if(arr[i] !== arr2[i]){
            return false
        }
    }
    return true
}
  • 14 链表奇偶位重排
 function oddEvenList( head ) {
    // write code here
    if(!head) return null
    let cur = head,key = head.next
    let even = key
    while(cur.next && even.next){ 
        cur.next = even.next
        cur = cur.next
        even.next = cur.next
        even = even.next
    }
    cur.next = key
    return head
}
  • 15 删除链表重复元素(保留一个)
function deleteDuplicates( head ) {
    // write code here
    let pre = head
    while(pre && pre.next){
        if(pre.val == pre.next.val){
            let temp = pre.next
            while(temp && pre.val == temp.val){
                temp = temp.next
            }
            pre.next = temp
            pre = pre.next
        }else{
            pre = pre.next
        }
    }
    return head
}
  • 16 删除链表重复元素(涉及元素全删)
function deleteDuplicates( head ) {
    // write code here
    let origin ={next:head}
    let pre = origin,cur = origin.next
    while(cur && cur.next){
        if(cur.val == cur.next.val){
            let temp = cur.next
            while(temp && temp.val == cur.val){
                temp = temp.next
            }
            pre.next = temp
            cur = temp
        }else{
            pre = pre.next
            cur = cur.next
        }
    }
    return origin.next
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值