5. K 个一组翻转链表

1. 25. K 个一组翻转链表

https://leetcode-cn.com/problems/reverse-nodes-in-k-group/

https://leetcode-cn.com/problems/reverse-nodes-in-k-group/ 
/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
 
/*
 1. 方法1:使用切片,分为len(ListNode)/k 组,然后分组反转,存入切片中,最后将切片中节点首尾相连
 执行用时 :8 ms , 内存消耗: 3.8 MB
*/
func reverseKGroup(head *ListNode, k int) *ListNode {
 	if head == nil || head.Next == nil {
		return head
	}
	cur := head
	var listLength int
	for head != nil {
		listLength++
		head = head.Next
	}

	reverseGroupNum := (listLength) / k
	if reverseGroupNum == 0 {
		return cur
	}

	var stack = make([]*ListNode, k*reverseGroupNum)
	for i := 0; i < reverseGroupNum; i++ {
		for j := 0; j < k; j++ {
			stack[(i+1)*k-j-1] = cur
			cur = cur.Next
		}
	}
	pre := new(ListNode)
	pre.Next = stack[0]
	for i := range stack {
		if i == (len(stack) - 1) {
			stack[i].Next = cur
			break
		}
		stack[i].Next = stack[i+1]
	}
	return pre.Next
}

/*
方法2: 使用分组递归和栈
//4ms,4M
*/
func reverseKGroup(head *ListNode, k int) *ListNode {
 	if head == nil || head.Next == nil {
		return head
	}
    var stack = make([]*ListNode, k)
    i := k
    node := head
    for k > 0 {
        stack[i-k] = node
        if node !=nil {
            node = node.Next
        }else{
            return head
        }
        k--
    }
    
    for k < i-1{  
        k++
        stack[i-k].Next = stack[i-k-1]
    }
    stack[0].Next = reverseKGroup(node, k+1)
    return stack[i-1]
}

/*
//尾插法
//8ms,3.8M
*/
func reverseKGroup(head *ListNode, k int) *ListNode {
 	if head == nil || head.Next == nil {
		return head
	}
    var dummy = new(ListNode)
    dummy.Next = head
    pre, tail := dummy, dummy
    tmp := pre
    firstReverse := true
    for{
        count := k
        for count>0 && tail != nil{
            tail = tail.Next
            count--
        }
        if tail == nil {
           break
        }
        
        firstNode := pre.Next
        for pre.Next != tail{
            cur := pre.Next
            pre.Next = cur.Next
            cur.Next = tail.Next
            tail.Next = cur
        }
        if firstReverse == true{
            tmp.Next = tail
            firstReverse = false
        }
        pre = firstNode
        tail = firstNode
    }

    return tmp.Next
}

/*
//8ms,3.6M
*/
func reverseKGroup(head *ListNode, k int) *ListNode {
 	if head == nil || head.Next == nil {
		return head
	}
    var dummy = new(ListNode)
    dummy.Next = head
    pre, tail := dummy, dummy

    for{
        count := k
        for count>0 && tail != nil{
            tail = tail.Next
            count--
        }
        if tail == nil {
           break
        }
        
        firstNode := pre.Next
        for pre.Next != tail{
            cur := pre.Next
            pre.Next = cur.Next  //第一次循环遍历结束后,因为dummy.Next=pre.Next=第一次K个反转后第一个元素
            cur.Next = tail.Next
            tail.Next = cur
        }

        pre = firstNode  //改变了pre地址,不再是dummy地址
        tail = firstNode
    }

    return dummy.Next
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值