Golang 链表排序、回文、合并K个有序列表

时间:2025-02-27 08:24:01

GItHub:/zhumengyifang/golangleetcode

数据结构:

type ListNode struct {
	Val int
	Next *ListNode
}

代码皆经过测试: 

/**
排序链表
*/
func SortListNode(head *) * {
	if head == nil {
		return nil
	}
	return mergeSort(head)
}

func mergeSort(head *) * {
	if  == nil {
		return head
	}
	p := head
	q := head
	var per *
	for ; q != nil &&  != nil; {
		per, p, q = p, , 
	}
	 = nil
	l := mergeSort(head)
	r := mergeSort(p)
	return merge(l, r)
}

func merge(l *, r *) * {
	dummyHead := &{}
	cur := dummyHead
	for ; l != nil && r != nil; {
		if  <=  {
			 = l
			cur = 
			l = 
		} else {
			 = r
			cur = 
			r = 
		}
	}
	if l != nil {
		 = l
	}
	if r != nil {
		 = r
	}
	return 
}

/**
回文链表
*/
func isPalindrome(head *) bool {
	if head == nil ||  == nil {
		return true
	}
	fast := head //快指针
	slow := head //慢指针

	for ;  != nil &&  != nil; {
		fast = 
		slow = 
	}

	slow = reverse()

	for ; slow != nil; {
		if  !=  {
			return false
		}
		head = 
		slow = 
	}
	return true
}

/**
反转链表
*/
func reverse(node *) * {
	if  == nil {
		return node
	}
	newHead := reverse()
	 = node
	 = nil
	return newHead
}

/**
环型链表
*/
func detectCycle(head *) * {
	slow := head
	fast := head
	isCycle := false
	//先用快慢指针判断是否是环形
	for ; fast != nil &&  != nil; {
		slow = 
		fast = 
		if slow == fast {
			isCycle = true
			break
		}
	}

	if isCycle {
		//慢指针不动,利用快指针找出环的大小
		cycleSize := 1
		fast = 
		for ; slow != fast; {
			fast = 
			cycleSize++
		}
		//根据环的大小,利用双指针找出环形入口,前后指针间隔为环的大小
		slow1 := head
		fast1 := head
		for ; cycleSize-1 > 0; {
			fast1 = 
			cycleSize--
		}
		//找入口的关键判断条件
		for ;  != slow1; {
			slow1 = 
			fast1 = 
		}
		return slow1
	}
	return nil
}

/**
合并K个链表
*/
func mergeKLists(lists []*) * {
	if lists == nil {
		return nil
	}
	var mergeListNode *
	for i := 0; i < len(lists); i++ {
		mergeListNode = merge(mergeListNode, lists[i])
	}
	return mergeListNode
}