如何解决在java中使用双向链表制作移动光标
我正在尝试在 Java 中为一个简单的移动光标编写代码。我必须使用双向链表。我也应该自己实现doubyLinkedList 类。在这个程序中,我们首先从用户那里取一个像 n
这样的整数作为行数。然后我们取 n 行输入。每行仅包含一个字符,可以是 <
或 >
或 -
或小写英文字母之一。对于 >
或 <
,我们将光标向右或向左移动。对于 -
,我们删除光标位置的字符。对于字母表,我们将它们添加到双向链表中。最后我们将结果打印在一行中,没有空格。我已经创建了doubyLinkedList 类和所需的方法。我认为它工作正常,但代码的时间复杂度必须是 O(n)
。我想现在是 O(n^2)
。
import java.util.*;
public class DoublyLinkedList {
static Node head = null;
static int size = 0;
class Node {
String data;
Node prev;
Node next;
Node(String d) {
data = d;
}
}
static Node deleteNode(Node del) {
if (head == null || del == null)
return null;
if (head == del)
head = del.next;
if (del.next != null)
del.next.prev = del.prev;
if (del.prev != null)
del.prev.next = del.next;
del = null;
size --;
return head;
}
public String GetNth(int index) {
Node current = head;
int count = 0;
while (current != null)
{ if (count == index)
return current.data;
count++;
current = current.next;
}
assert (false);
return null;
}
public static void deleteNodeAtGivenPos(int n) {
size--;
if (head == null || n <= 0)
return;
Node current = head;
int i;
for (i = 1; current != null && i < n; i++)
current = current.next;
if (current == null)
return;
deleteNode(current);
}
void insertFirst (String data){
size++;
Node newNode = new Node(data);
if (head == null) {
newNode.prev = null;
head = newNode;
return;
}
else
head.prev= newNode;
newNode.next=head;
head = newNode;
}
void append(String data) {
size++;
Node newNode = new Node(data);
Node last = head;
newNode.next = null;
if (head == null) {
newNode.prev = null;
head = newNode;
return;
}
while (last.next != null)
last = last.next;
last.next = newNode;
newNode.prev = last;
}
public void insertAtGivenPos(String s,int index){
Node newNode= new Node(s);
Node current= head;
if (index==0)
insertFirst(s);
else if(index==size)
append(s);
else{
for(int j = 0; j < index && current.next != null; j++){
current = current.next;
}
newNode.next = current;
current.prev.next = newNode;
newNode.prev = current.prev;
current.prev = newNode;
size++;
}
}
public void print(Node node) {
while (node != null) {
System.out.print(node.data + "");
node = node.next;
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(system.in);
int n = Integer.parseInt(sc.nextLine());
String [] arr= new String[n];
for (int i=0; i< n; i++)
arr[i] = sc.nextLine();
DoublyLinkedList dll = new DoublyLinkedList();
int cursor= 0;
for (int i=0; i< n; i++){
if (arr[i].matches("[a-z]")){
dll.insertAtGivenPos(arr[i],cursor);
cursor++;
}
else if (arr[i].contains("-")&& dll.GetNth(cursor-1)!= null) {
dll.deleteNodeAtGivenPos(cursor);
cursor--;
}
else if (arr[i].contains("<") && dll.GetNth(cursor-1)!= null)
cursor--;
else if (arr[i].contains(">") && dll.GetNth(cursor+1)!= null)
cursor++;
}
dll.print(dll.head);
}
}
如何改进代码以降低时间复杂度?
编辑:我也明白我的代码在某些情况下给出了错误的答案。你能帮我调试一下吗?
解决方法
如果你不是被迫遵循实现细节,我建议不要有游标。相反,保留一个变量 currentNode
,它是 cursor
将指向的节点。因此,对于输入循环中的每个命令(或数据),您都有一个 O(1) 操作,如下所示,因此将获得 O(n) 时间复杂度。
1 - 对于 >
:将 currentNode
更改为 currentNode.next
2 - <
做相反的事情
3 - 对于 -
将 currentNode
的上一个和下一个节点更改为
点的情况下(因此当前被删除)
4 - 最后用于插入:创建一个节点并像 3
一样,更改
指向它的侧节点
您不需要内部 for 循环。接受后立即处理输入。
for (int i=0; i< n; i++)
arr[i] = sc.nextLine();
DoublyLinkedList dll = new DoublyLinkedList();
int cursor= 0;
if (arr[i].matches("[a-z]")){
dll.insertAtGivenPos(arr[i],cursor);
cursor++;
}
else if (arr[i].contains("-")&& dll.GetNth(cursor-1)!= null) {
dll.deleteNodeAtGivenPos(cursor);
cursor--;
}
else if (arr[i].contains("<") && dll.GetNth(cursor-1)!= null)
cursor--;
else if (arr[i].contains(">") && dll.GetNth(cursor+1)!= null)
cursor++;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。