Algorithm 从链接列表中删除和等于零的元素

Algorithm 从链接列表中删除和等于零的元素,algorithm,Algorithm,给定一个链表形式的列表,我必须取消所有总和为0(零)的资源,并返回剩余的列表 像 我只需要算法来解决这个问题 这实际上是经典的子集和问题,它是NP完全问题 请参阅on或google it以查看有关假设的文章:只有求和为零的连续元素才能删除。 遵循的方法: 1.将链接列表中的非零元素推送到堆栈中。 2.出现非零元素时: (a) 迭代堆栈,弹出每个元素并继续添加到非零元素。 (b) 继续将pop元素添加到列表中。 (c) 如果值为零(这意味着现在您已经删除了),则中断堆栈迭代。 (d) 如果堆栈

给定一个链表形式的列表,我必须取消所有总和为0(零)的资源,并返回剩余的列表


我只需要算法来解决这个问题

这实际上是经典的子集和问题,它是NP完全问题


请参阅on或google it以查看有关假设的文章:

只有求和为零的连续元素才能删除。
遵循的方法:
1.将链接列表中的非零元素推送到堆栈中。
2.出现非零元素时:
(a) 迭代堆栈,弹出每个元素并继续添加到非零元素。
(b) 继续将pop元素添加到列表中。
(c) 如果值为零(这意味着现在您已经删除了),则中断堆栈迭代。
(d) 如果堆栈为空&总和!=0将列表元素与非零元素一起添加到堆栈中

尝试以下代码:

    public class ElementSumNonZero {

    private static Node head;

    private static class Node {
        int data;
        Node next;

        Node(int d) {
            data = d;
            next = null;
        }
    }

    private void removeNonZeroElements(Node root) {
     Node start = root;
     Stack<Node> stack = new Stack<>();
     boolean flag = false;
     List<Node> list = new ArrayList<>();
     while (start != null) {
        if (start.data > 0)
            stack.push(start);
        else {
            int sum = start.data;
            flag = false;
            while (!stack.isEmpty()) {
                Node temp = stack.pop();
                sum += temp.data;
                if (sum == 0) {
                    flag = true;
                    list.clear();
                    break;
                }
                list.add(temp);
            }
            if (!flag) {
                list.forEach(i -> stack.add(i));
                stack.add(start);
            }
        }
        start = start.next;
     }
     stack.forEach(i -> System.out.print(i.data +" -> "));
     System.out.println("NULL");
   }

    // Driver program to test above functions
    public static void main(String[] args) {
        ElementSumNonZero list = new ElementSumNonZero();
        ElementSumNonZero.head = new Node(6);
        ElementSumNonZero.head.next = new Node(-6);
        ElementSumNonZero.head.next.next = new Node(8);
        ElementSumNonZero.head.next.next.next = new Node(4);
        ElementSumNonZero.head.next.next.next.next = new Node(-12);
        ElementSumNonZero.head.next.next.next.next.next = new Node(9);
        ElementSumNonZero.head.next.next.next.next.next.next = new Node(8);
        ElementSumNonZero.head.next.next.next.next.next.next.next = new Node(-8);

        list.removeNonZeroElements(head);
    }
}
公共类元素sumnonzero{
专用静态节点头;
私有静态类节点{
int数据;
节点下一步;
节点(int d){
数据=d;
next=null;
}
}
私有void removeNonZeroElements(节点根){
节点开始=根;
堆栈=新堆栈();
布尔标志=假;
列表=新的ArrayList();
while(开始!=null){
如果(start.data>0)
堆栈推送(启动);
否则{
int sum=start.data;
flag=false;
而(!stack.isEmpty()){
Node temp=stack.pop();
总和+=温度数据;
如果(总和=0){
flag=true;
list.clear();
打破
}
列表。添加(临时);
}
如果(!标志){
list.forEach(i->stack.add(i));
stack.add(开始);
}
}
start=start.next;
}
stack.forEach(i->System.out.print(i.data+“->”);
System.out.println(“空”);
}
//用于测试上述功能的驱动程序
公共静态void main(字符串[]args){
ElementSumNonZero list=新ElementSumNonZero();
ElementSumNonZero.head=新节点(6);
ElementSumNonZero.head.next=新节点(-6);
ElementSumNonZero.head.next.next=新节点(8);
ElementSumNonZero.head.next.next.next=新节点(4);
ElementSumNonZero.head.next.next.next.next=新节点(-12);
ElementSumNonZero.head.next.next.next.next=new节点(9);
ElementSumNonZero.head.next.next.next.next.next=新节点(8);
ElementSumNonZero.head.next.next.next.next.next.next=新节点(-8);
列表。删除零元素(head);
}
}
测试0
原文:{6,-6,6,8,4,-12,9,8,-8}
取消了:{9}

测试1
原件:{4,6,10,8,9,10,19,10,18,20,25}
取消了:{20,25}

我们可以将结果堆栈创建到链接列表中,并从“removeNonZeroElements”方法返回。

请纠正我的错误,并建议如何使此代码更有效。

以下函数仅打印节点(已取消的节点除外),您可以将其推送到新列表并返回

void printExCancel( node* head )
{
    node* start = head;
    node* end;

    while ( start )
    {
        bool mod = false;
        int sum = 0;
        end = start;
        while ( end )
        {
            sum += end->data;
            if ( sum == 0 )
            {
                start = end;
                mod = true;
                break;
            }
            end = end->next;
        }
        if ( mod == false ) {
            //push to new list
            printf( "%d\n", start->data );
        }
        //else {
        //    call funtion to delete from start to end
        //}
        start = start->next;
    }
}
以下python代码也通过了这两个测试用例:
“”“删除链表中总和等于零的元素
例如-->>6-684-1298-8
上面的示例列出了哪些被取消:
6 -6
8 4 -12
8 -8
o/p:9
案例3:46-108910-1910-1825
O/P:20 25英寸
#v_list=[6,-6,8,4,-12,9,8,-8]
#建筑节点
类节点():
定义初始值(自身,值):
自我价值=价值
self.nextnode=None
#用于指向头部和尾部的类链接列表
类LinkedList():
定义初始化(自):
self.head=无
def添加元素(自身、值):
节点=节点(值)
如果self.head为无:
self.head=节点
返回
crnt_节点=self.head
尽管如此:
如果crnt_node.nextnode为无:
crnt_node.nextnode=node
打破
crnt\u node=crnt\u node.nextnode
def打印列表(自身):
crnt_节点=self.head
v_llist=[]
尽管如此:
打印(crnt_node.value,end='->')
v_llist.append(crnt_node.value)#将数据存储到列表中
如果crnt_node.nextnode为无:
打破
crnt\u node=crnt\u node.nextnode
打印('无')
返回v_llist
def打印修改列表(自身):
p_add=0
v_llist=self.print_llist()
#一直到列表的最后一个元素,然后尝试打印请求的o/p
对于范围内的i(len(v_llist)-1):
p_add=p_add+v_llist[i]
如果v_llist[-1]>0且p_add>0:
打印(p_add,v_llist[-1])
elif v_llist[-1]0:
打印(p_添加+v_列表[-1])

在第二个示例中,如果输入是
8 10 1 4 3-1-3
,结果会是什么?如果我可以返回较小的列表,8 10 4或8 10 1 3都会更好。总和为零的项目是否总是连续的?也就是说,您会一直使用
6-632-544
还是也可以使用
64-532-622
?因为您的示例似乎满足第一种情况,在这种情况下,“最愚蠢”的算法可能是“仅”
O(n^2)
(对于每个起始索引
i
,循环列表的其余部分,直到到达末尾或找到零和子集)。否,它们不需要是连续的。请将您的答案始终放在上下文中,而不仅仅是粘贴代码。有关更多详细信息,请参阅。
void printExCancel( node* head )
{
    node* start = head;
    node* end;

    while ( start )
    {
        bool mod = false;
        int sum = 0;
        end = start;
        while ( end )
        {
            sum += end->data;
            if ( sum == 0 )
            {
                start = end;
                mod = true;
                break;
            }
            end = end->next;
        }
        if ( mod == false ) {
            //push to new list
            printf( "%d\n", start->data );
        }
        //else {
        //    call funtion to delete from start to end
        //}
        start = start->next;
    }
}
class Node():
  def __init__(self,data):
     self.data = data
     self.next = None

class Linkedlist():
   def __init__(self):
     self.head = None
    
   def append(self,data):
     new_node = Node(data)
     h = self.head
     if self.head is None:
         self.head = new_node
         return
     else:
         while h.next!=None:
             h = h.next
         h.next = new_node

   def remove_zeros_from_linkedlist(self, head):
     stack = []
     curr = head
     list = []
     while (curr):
         if curr.data >= 0:
             stack.append(curr)
         else:
             temp = curr
             sum = temp.data
             flag = False
             while (len(stack) != 0):
                 temp2 = stack.pop()
                 sum += temp2.data
                 if sum == 0:
                     flag = True
                     list = []
                     break
                 elif sum > 0:
                     list.append(temp2)
             if not flag:
                 if len(list) > 0:
                     for i in range(len(list)):
                         stack.append(list.pop())
                 stack.append(temp)
         curr = curr.next
     return [i.data for i in stack]

if __name__ == "__main__":
 l = Linkedlist()

 l.append(4)
 l.append(6)
 l.append(-10)
 l.append(8)
 l.append(9)
 l.append(10)
 l.append(-19)
 l.append(10)
 l.append(-18)
 l.append(20)
 l.append(25)
 print(l.remove_zeros_from_linkedlist(l.head))
'''Delete the elements in an linked list whose sum is equal to zero
E.g-->> 6 -6 8 4 -12 9 8 -8
the above example lists which gets canceled :
6 -6
8 4 -12
8 -8
o/p : 9
case 3 : 4 6 -10 8 9 10 -19 10 -18 20 25
O/P : 20 25'''

#v_list=[6 ,-6, 8, 4, -12, 9, 8, -8]
#Building Nodes
class Node():
    def __init__(self,value):
        self.value=value
        self.nextnode=None
#Class Linked List for Pointing Head and Tail
class LinkedList():
    def __init__(self):
        self.head=None
    
    def add_element(self,value):
        node=Node(value)
        if self.head is None:
            self.head=node
            return
        crnt_node=self.head
        while True:
            if crnt_node.nextnode is None:
                crnt_node.nextnode=node
                break
            crnt_node=crnt_node.nextnode

    def print_llist(self):
        crnt_node=self.head     
        v_llist=[]
        while True:
            print(crnt_node.value,end='->')
            v_llist.append(crnt_node.value) # storing data into list
            if crnt_node.nextnode is None:              
                break
            crnt_node=crnt_node.nextnode
        print('None')
        return v_llist
        
    def print_modified_llist(self):
        p_add=0
        v_llist=self.print_llist()
        #going till the second last element of list and then trying to print requested o/p
        for i in range(len(v_llist)-1):
            p_add=p_add+v_llist[i]
        if v_llist[-1]>0 and p_add>0:
            print(p_add,v_llist[-1])
        elif v_llist[-1]<0 and p_add>0:
            print(p_add+v_list[-1])
        elif v_llist[-1]<0 and p_add<0:
            print(v_llist[-1],p_add)
            

sll=LinkedList()
sll.add_element(4)
sll.print_llist()
sll.add_element(6)
sll.print_llist()
sll.add_element(-10)
sll.print_llist()
sll.add_element(8)
sll.print_llist()
sll.add_element(9)
sll.print_llist()
sll.add_element(10)
sll.print_llist()
sll.add_element(-19)
sll.print_llist()
sll.add_element(10)
sll.print_llist()
sll.add_element(-18)
sll.print_llist()
sll.add_element(20)
sll.print_llist()
sll.add_element(25)
sll.print_llist()
sll.print_modified_llist()