Le titre de cet article vient de leetcode
avant-propos
Bonjour à tous, je suis Xiao Yu, et aujourd'hui j'ai résolu un problème difficile lié aux listes chaînées : un groupe de K listes chaînées renversées.
Question
Donnez-vous le nœud principal de la liste chaînée head
, retournez k
chaque nœud dans un groupe, veuillez renvoyer la liste chaînée modifiée.
k
est un entier positif dont la valeur est inférieure ou égale à la longueur de la liste chaînée. Si le nombre total de nœuds k
n'est pas un multiple entier de , veuillez conserver les derniers nœuds restants dans l'ordre d'origine.
Vous ne pouvez pas simplement changer la valeur à l'intérieur du nœud, mais vous devez réellement échanger le nœud.
Exemple 1:
输入:head = [1,2,3,4,5], k = 2
输出:[2,1,4,3,5]
indice:
- Le nombre de nœuds dans la liste chaînée est
n
1 <= k <= n <= 5000
0 <= Node.val <= 1000
Solution
En voyant cette question, la première réaction est la méthode de simulation la plus intuitive. Tout d'abord, écrivez une fonction auxiliaire pour retourner la liste chaînée, puis continuez à trouver l'intervalle qui doit être retourné et retournez-le. Parmi eux, il faut faire attention aux nœuds dans la première moitié et la seconde moitié de l'intervalle de retournement. Dans le même temps, afin de renvoyer le nœud de résultat correct, un indicateur est également défini pour identifier s'il s'agit du premier retournement. S'il s'agit du premier retournement, le nœud principal doit être défini. Le code spécifique est le suivant :
Code
type ListNode struct {
Val int
Next *ListNode
}
func reverseKGroup(head *ListNode, k int) *ListNode {
var result *ListNode
var resultflag bool
var reverse func(head *ListNode, tail *ListNode) *ListNode
//只翻转head到tail的节点,前后节点并未处理
reverse = func(head *ListNode, tail *ListNode) *ListNode {
var pre *ListNode
now := head
for pre != tail {
temp := now.Next
now.Next = pre
pre = now
now = temp
}
return pre
}
tempnode := head
var pre *ListNode
var start *ListNode
var end *ListNode
for tempnode != nil {
flag := true
start, end = tempnode, tempnode
for i := 0; i < k-1; i++ {
end = end.Next
if end == nil {
flag = false
break
}
}
if !flag {
if !resultflag {
result = start
}
pre.Next = start
return result
} else {
tempnode = end.Next
node := reverse(start, end)
if resultflag {
pre.Next = node
pre = start
} else {
result = node
resultflag = true
pre = start
}
}
}
return result
}
Résumer
Lorsque vous posez des questions de liste chaînée, n'ayez pas peur d'avoir trop de variables ! Définissez quelques variables supplémentaires afin qu'il ne soit pas facile de faire des erreurs lors de l'écriture de la logique. Par exemple, dans cette question, utilisez la variable tempnode pour identifier à quel nœud vous vous trouvez actuellement, utilisez les variables de début et de fin pour identifier le pré-flip intervalle, et utilisez le pré Pour identifier le nœud précédent, en fait, l'identification à l'intérieur est quelque peu redondante, mais l'augmentation de la lisibilité du code est évidente pour tous.