[英]Singly linked list in java
我剛剛在網上找到了這個困難的面試問題,我希望有人可以幫助我理解它。 這是一個通用的問題......給定一個單鏈表,將列表中的每個元素成對交換,使1-> 2-> 3-> 4成為2-> 1-> 4-> 3。
您必須交換元素,而不是值。 答案應該適用於循環列表,其中尾部指向列表的頭部。 您不必檢查尾部是否指向中間(非頭部)元素。
所以我認為:
public class Node
{
public int n; // value
public Node next; // pointer to next node
}
實現這個的最佳方法是什么? 有人可以幫忙嗎?
Java中的簡單遞歸解決方案:
public static void main(String[] args)
{
Node n = new Node(1);
n.next = new Node(2);
n.next.next = new Node(3);
n.next.next.next = new Node(4);
n.next.next.next.next = new Node(5);
n = swap(n);
}
public static Node swap(Node n)
{
if(n == null || n.next == null)
return n;
Node buffer = n;
n = n.next;
buffer.next = n.next;
n.next = buffer;
n.next.next = swap(buffer.next);
return n;
}
public static class Node
{
public int data; // value
public Node next; // pointer to next node
public Node(int value)
{
data = value;
}
}
我同意@Stephen沒有給出答案(完全),但我想我應該給你提示。
要理解的一件重要事情是Java沒有顯式指定指針 - 相反,只要非基元(例如,不是char
, byte
, int
, double
, float
, long
, boolean
, short
)傳遞給函數,它就會被傳遞為一個參考。 因此,您可以使用臨時變量來交換值。 嘗試自己編寫代碼或查看以下內容:
public static void swapNodeNexts(final Node n1, final Node n2) {
final Node n1Next = n1.next;
final Node n2Next = n2.next;
n2.next = n1Next;
n1.next = n2Next;
}
然后,您將需要一個數據結構來保存Node
。 重要的是只有偶數個Node
(奇數不必要地使事情變得復雜)。 還需要初始化節點。 你應該把它放在你的main方法中。
public static final int NUMPAIRS = 3;
public static void main(final String[] args) {
final Node[] nodeList = new Node[NUMPAIRS * 2];
for (int i = 0; i < nodeList.length; i++) {
nodeList[i] = new Node();
nodeList[i].n = (i + 1) * 10;
// 10 20 30 40
}
// ...
}
重要的是設置Node下一個值。 你不能只是通過一個循環for
回路所有的人,因為這樣最后一個人的next
會拋出IndexOutOfBoundsException
。 試着自己制作一個,或偷看我的。
for (int i = 0; i < nodeList.length - 1; i++) {
nodeList[i].next = nodeList[i + 1];
}
nodeList[nodeList.length - 1].next = nodeList[0];
然后使用for
循環在它們上運行swap函數。 但請記住,你不想在每個節點上運行它......想一想。
如果你無法弄清楚,這是我的最終代碼:
// Node
class Node {
public int n; // value
public Node next; // pointer to next node
@Override
public String toString() {
return "Node [n=" + n + ", nextValue=" + next.n + "]";
}
}
// NodeMain
public class NodeMain {
public static final int NUMPAIRS = 3;
public static void main(final String[] args) {
final Node[] nodeList = new Node[NUMPAIRS * 2];
for (int i = 0; i < nodeList.length; i++) {
nodeList[i] = new Node();
nodeList[i].n = (i + 1) * 10;
// 10 20 30 40
}
for (int i = 0; i < nodeList.length - 1; i++) {
nodeList[i].next = nodeList[i + 1];
}
nodeList[nodeList.length - 1].next = nodeList[0];
// This makes 1 -> 2 -> 3 -> 4 -> 1 etc.
printNodes(nodeList);
for (int i = 0; i < nodeList.length; i += 2) {
swapNodeNexts(nodeList[i], nodeList[i + 1]);
}
// Now: 2 -> 1 -> 4 -> 3 -> 1 etc.
printNodes(nodeList);
}
private static void printNodes(final Node[] nodeList) {
for (int i = 0; i < nodeList.length; i++) {
System.out.println("Node " + (i + 1) + ": " + nodeList[i].n
+ "; next: " + nodeList[i].next.n);
}
System.out.println();
}
private static void swapNodeNexts(final Node n1, final Node n2) {
final Node n1Next = n1.next;
final Node n2Next = n2.next;
n2.next = n1Next;
n1.next = n2Next;
}
}
我希望你能夠在指導下弄清楚其中的一部分。 但更重要的是,了解這里的概念非常重要。 如果您有任何疑問,請發表評論。
運行此程序所需的方法:
public static void main(String[] args) {
int iNoNodes = 10;
System.out.println("Total number of nodes : " + iNoNodes);
Node headNode = NodeUtils.createLinkedListOfNElements(iNoNodes);
Node ptrToSecondNode = headNode.getNext();
NodeUtils.printLinkedList(headNode);
reversePairInLinkedList(headNode);
NodeUtils.printLinkedList(ptrToSecondNode);
}
方法幾乎相同,其他人正試圖解釋。 代碼是自我解釋的。
private static void reversePairInLinkedList(Node headNode) {
Node tempNode = headNode;
if (tempNode == null || tempNode.getNext() == null)
return;
Node a = tempNode;
Node b = tempNode.getNext();
Node bNext = b.getNext(); //3
b.setNext(a);
if (bNext != null && bNext.getNext() != null)
a.setNext(bNext.getNext());
else
a.setNext(null);
reversePairInLinkedList(bNext);
}
Algo(節點n1) -
在當前的2個節點保留2個指針n1和n2。 n1 - > n2 ---> ......
if(n1和n2相互鏈接)返回n2;
if(n1為NULL)返回NULL;
if(n2為NULL)返回n1;
if(n1和n2不相互鏈接且不為空)
將n2的指針更改為n1。
在n2.next上遞歸調用algorthm
返回n2;
用c ++編寫代碼(工作)
#include <iostream>
using namespace std;
class node
{
public:
int value;
node* next;
node(int val);
};
node::node(int val)
{
value = val;
}
node* reverse(node* n)
{
if(n==NULL) return NULL;
node* nxt = (*n).next;
if(nxt==NULL) return n;
if((*nxt).next==n) return nxt;
else
{
node* temp = (*nxt).next;
(*nxt).next = n;
(*n).next = reverse(temp);
}
return nxt;
}
void print(node* n)
{
node* temp = n;
while(temp!=NULL)
{
cout<<(*temp).value;
temp = (*temp).next;
}
cout << endl;
}
int main()
{
node* n = new node(0);
node* temp = n;
for(int i=1;i<10;i++)
{
node* n1 = new node(i);
(*temp).next = n1;
temp = n1;
}
print(n);
node* x = reverse(n);
print(x);
}
//2.1 , 2.2 Crack the code interview
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
struct Node{
int info;
struct Node *next;
};
struct Node *insert(struct Node *head,int data){
struct Node *temp,*ptr;
temp = (struct Node*)malloc(sizeof(struct Node));
temp->info=data;
temp->next=NULL;
if(head==NULL)
head=temp;
else{
ptr=head;
while(ptr->next!=NULL)
{
ptr=ptr->next;
}
ptr->next=temp;
}
return head;
}
struct Node* reverse(struct Node* head){
struct Node *current,*prev,*next;
current = head;
prev=NULL;
while(current!=NULL){
next=current->next;
current->next = prev;
prev=current;
current=next;
}
head=prev;
return head;
}
/*nth till last element in linked list*/
void nthlastElement(struct Node *head,int n){
struct Node *ptr;
int last=0,i;
ptr=head;
while(ptr!=NULL){
last++;
//printf("%d\n",last);
ptr=ptr->next;
}
ptr=head;
for(i=0;i<n-1;i++){
ptr=ptr->next;
}
for(i=0;i<=(last-n);i++){
printf("%d\n",ptr->info);
ptr=ptr->next;
}
}
void display(struct Node* head){
while(head!=NULL){
printf("Data:%d\n",head->info);
head=head->next;
}
}
void deleteDup(struct Node* head){
struct Node *ptr1,*ptr2,*temp;
ptr1=head;
while(ptr1!=NULL&&ptr1->next!=NULL){
ptr2=ptr1;
while(ptr2->next!=NULL){
if(ptr1->info==ptr2->next->info){
temp=ptr2->next;
ptr2->next=ptr2->next->next;
free(temp);
}
else{
ptr2=ptr2->next;
}
}
ptr1=ptr1->next;
}
}
void main(){
struct Node *head=NULL;
head=insert(head,10);
head=insert(head,20);
head=insert(head,30);
head=insert(head,10);
head=insert(head,10);
printf("BEFORE REVERSE\n");
display(head);
head=reverse(head);
printf("AFTER REVERSE\n");
display(head);
printf("NTH TO LAST\n");
nthlastElement(head,2);
//printf("AFTER DUPLICATE REMOVE\n");
//deleteDup(head);
//removeDuplicates(head);
//display(head);
}
采用的一般方法是逐步執行列表,並在每個其他步驟中通過分配node
值對列表節點重新排序。
但是,如果您自己設計,實施和測試,我認為您將從中獲得更多(即了解更多)。 (你在面試時沒有得到免費的“打電話給朋友”或“問SO”)
是的,編寫一個迭代例程,在每次迭代中前進兩個鏈接。 記住上一次迭代的鏈接,以便您可以對其進行補丁,然后交換當前的兩個鏈接。 棘手的部分是開始(在很小程度上)並知道何時完成(更大的),特別是如果你最終有一個奇數個元素。
public static Node swapInPairs(Node n)
{
Node two;
if(n ==null ||n.next.next ==null)
{
Node one =n;
Node twoo = n.next;
twoo.next = one;
one.next =null;
return twoo;
}
else{
Node one = n;
two = n.next;
Node three = two.next;
two.next =one;
Node res = swapInPairs(three);
one.next =res;
}
return two;
}
我在原子級寫了代碼。 所以我希望它是自我解釋的。 我測試了它。 :)
public static Node swapPairs(Node start)
{
// empty or one-node lists don't need swapping
if (start == null || start.next == start) return start;
// any list we return from here on will start at what's the second node atm
Node result = start.next;
Node current = start;
Node previous = null; // so we can fix links from the previous pair
do
{
Node node1 = current;
Node node2 = current.next;
// swap node1 and node2 (1->2->? ==> 2->1->?)
node1.next = node2.next;
node2.next = node1;
// If prev exists, it currently points at node1, not node2. Fix that
if (previous != null) previous.next = node2;
previous = current;
// only have to bump once more to get to the next pair;
// swapping already bumped us forward once
current = current.next;
} while (current != start && current.next != start);
// The tail needs to point at the new head
// (if current == start, then previous is the tail, otherwise current is)
((current == start) ? previous : current).next = result;
return result;
}
public class Node
{
public int n; // value
public Node next; // pointer to next node
}
Node[] n = new Node[length];
for (int i=0; i<n.length; i++)
{
Node tmp = n[i];
n[i] = n[i+1];
n[i+1] = tmp;
n[i+1].next = n[i].next;
n[i].next = tmp;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.