[Title] algorithm to merge two lists _ sort of problem solutions as well as problems that may arise

The main explanation writing code at one speed when taking into account the relatively fast problem-solving program possible problems.

Go solving Code

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode {
    newList := &ListNode{0, nil}
    currentNode := newList
    for l1 != nil && l2 != nil {
        var num int
        if l1.Val > l2.Val {
            num = l2.Val
            l2 = l2.Next
        } else {
            num = l1.Val
            l1 = l1.Next
        }
        currentNode.Next = &ListNode{num, nil}
        currentNode = currentNode.Next
    }
    //标记(1)
    if l1 != nil {
        currentNode.Next = l1
    } else {
        currentNode.Next = l2
    }
    
    return newList.Next
}

There is a problem

Tag (1) where, l1 or l2 may exist and there is only one list traversal is not complete (i.e.,:! L1 or l2 = nil), can be traversed directly incompletely linked list node that the new list of pointers as a node pointer. !!! This is the way to speed up the implementation of efficiency, but because they belong to a pointer operation, if inadvertently change or release the content of the list l1 or l2, may cause access problems when the new list of pointers, access to unknown data, there security issues.

Trigger test questions (Go seemed less manually release the memory variables, usually GC handled automatically, so wrote the relative may occur):

func main() {
	l2 := &ListNode{1, nil}
	ret := mergeTwoLists(nil, l2)
	fmt.Println(ret.Val)
	l2.Val = 2
	fmt.Println(ret.Val)
}

Output:
1
2 // test case here because the value of l2 node changes, resulting in the value of the new list also will be changed.

The relative safety of solving the code

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode {
    newList := &ListNode{0, nil}
    currentNode := newList
    for l1 != nil && l2 != nil {
        var num int
        if l1.Val > l2.Val {
            num = l2.Val
            l2 = l2.Next
        } else {
            num = l1.Val
            l1 = l1.Next
        }
        currentNode.Next = &ListNode{num, nil}
        currentNode = currentNode.Next
    }
    
	//标记(2)
    for l2 != nil {
        currentNode.Next = &ListNode{l2.Val, nil}
        currentNode = currentNode.Next
        l2 = l2.Next
    }
    
    for l1 != nil {
        currentNode.Next = &ListNode{l1.Val, nil}
        currentNode = currentNode.Next
        l1 = l1.Next
    }
    
    return newList.Next
}

Explanation

(2) The following code only at the code mark with numeral 1 is different, the first problem-solving code direct reference pointer manner, instead of the original value list remaining incompletely traversed nodes to add added to the new way of the list, as far as possible to ensure that the new list data can not be accidentally modified.

Published 18 original articles · won praise 8 · views 30000 +

Guess you like

Origin blog.csdn.net/qq_20408397/article/details/104672118