查找链表

时间:2018-05-25 10:54:56

标签: algorithm sorting linked-list

给定除了单个元素之外的非递减顺序的数字链接列表,找到单个不合适的元素。

我觉得必须有一个简单的算法,但我无法弄清楚。你不能真正只是将当前数字与最后一个数字进行比较,因为你有像这样的情况1,2,5,3,5,其中3将被错误地返回为不合适的元素。

这是我的代码:

Node* fix(Node* head) {
    if (!head || !head->next) return head;

    Node* curr = head;
    Node* prev = head;
    Node* wrongNode = head;
    Node* wrongPrev = head;


    while (curr) {
        if ((!curr->next && prev->val > curr->val) || //if at beginning or end, its outofplace
             (curr == head && curr->val > curr->next->val)) {
            wrongNode = curr;
            wrongPrev = prev;
            break;
        }

        if (curr->next && ((prev->val < curr->val && curr->next->val < curr->val) ||
             (prev->val > curr->val && curr->next->val > curr->val))) { // if both sides of element are either larger or smaller, it might be outofplace. Check by running through the list to see if list is in correct order if you skip the element.
            wrongNode = curr;
            wrongPrev = prev;

            Node* temp = head;
            Node* tempPrev = head;
            while (temp && tempPrev->val <= temp->val) {
                tempPrev = temp;
                if (temp->next == curr) temp = temp->next->next;
                else temp = temp->next;
            }

            if (!temp) break;
        }

        prev = curr;
        curr = curr->next;
    }

    if (wrongNode == head) head = wrongNode->next;
    else wrongPrev->next = wrongNode->next;
    curr = head, prev = head;


    while (curr && wrongNode->val > curr->val) {
        prev = curr;
        curr = curr->next;
    }

    if (curr == head)   head = wrongNode;
    else prev->next = wrongNode;
    wrongNode->next = curr;

    return head;
}

我基本上扫描列表,如果我在开头找到一个大于下一个的元素,或者在末尾的元素小于之前的元素,则该元素必须是不合适的元素

如果不是这种情况,我会搜索一个元素k,它在前后都有一个元素,它们既可以大于k,也可以小于k。然后,我尝试看看列表是否在没有k的情况下处于非递减顺序。如果是,k是不合适的。如果没有,那一定是下一个(我想)。

然后我将k插入正确的位置。

有可能的输入,如

1,0其中1或0不合适。

1,2,5,6,4,7其中4不合适。

1,2,5,3,4其中5不合适。

7,1,2,其中7不合适。

有一种更简单的方法可以做到这一点。我只是没有看到它。

2 个答案:

答案 0 :(得分:2)

使用当前元素和上一元素的差异线性扫描列表。如果差异为负,则当前或前一项目不合适。至少在您的情况下,可以通过试用删除“当前”来检查这一点。如果删除导致负差异的元素不能修复列表,则删除前一个必须。

List : 1  2  5  6  4  7
diff =    1  3  1 -2  3
Trial: 1  2  5  6  *  7 --> correct
       1  2  5  *  4  7 --> incorrect (no need to check)

List : 7  1  2
diff :   -6  1
Trial: 7  *  2  --> incorrect
Trial: *  1  2  --> correct (no need to test)

答案 1 :(得分:0)

<强>的假设

  • 列表处于非递减顺序。
  • 列表的长度大于2,并且at most 1元素无序。

我在java尝试过。

链接列表的定义

class ListNode{
    int data;
    ListNode next;
    ListNode(int d){
        data = d;
        next = null;
    }
}

<强>算法

  • 迭代元素列表。
  • 现在,如果当前元素大于下一个元素 -
    • 如果在下一个元素之后仍然存在元素,我们将比较窗口移动到current,next,next to next
    • 如果在下一个元素之后存在no element,我们会将比较窗口移至prev,curr,next

<强>代码:

class ListNode{
    int data;
    ListNode next;
    ListNode(int d){
        data = d;
        next = null;
    }
}

public class Solution {
    public static void main(String[] args) {

        int[][] test = {
                        {1,2,5,3,5},
                        {1,2,5,1},
                        {1,2,5,2},
                        {7,1,2},
                        {1,2,5,6,4,7},
                        {1,2,3,4,5,6,7},
                        {1,2,5,3,4},
                        {1,2,5,3,5,6,7},
                        {1,2,5,3,4,4,4},
                        {2,3,2},
                        {3,3,2}
        };

        for(int i=0;i<test.length;++i){
            ListNode head = new ListNode(test[i][0]);
            ListNode temp = head;

            for(int j=1;j<test[i].length;++j){
                ListNode newNode = new ListNode(test[i][j]);
                temp.next = newNode;
                temp = newNode;
            }

            temp = findOutOfOrderElement(head);
            System.out.println(temp == null ? "No out of place element" : temp.data);  
        }        
    }

    private static ListNode findOutOfOrderElement(ListNode head){

        ListNode ptr  = head;
        ListNode prev = null;

        while(ptr != null && ptr.next != null){
            if(ptr.data > ptr.next.data){
                if(ptr.next.next == null){
                    if(prev == null) return ptr;
                    if(prev.data > ptr.next.data) return ptr.next;
                    else return ptr;
                }else{
                    if(ptr.data <= ptr.next.next.data) return ptr.next;
                    return ptr;
                }
            }

            prev = ptr;
            ptr= ptr.next;            
        }

        return null;
    }

}

<强>输出

3
1
5
7
4
No out of place element
5
3
5
3
2