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