【问题标题】:Given a linked list of numbers. Swap every 2 adjacent links给定一个数字链表。每 2 个相邻链接交换一次
【发布时间】:2010-05-15 04:27:52
【问题描述】:

给定一个数字链表。每 2 个相邻链接交换一次。例如,如果给你一个链表是:

a->b->c->d->e->f 

预期输出:

b->a->d->c->f->e

每 2 个备用链接必须交换。

我在这里写了一个解决方案。你能建议我一些其他的解决方案吗?您能评论我的解决方案并帮助我更好地编写它吗?

void SwapAdjacentNodes (Node head)
{
    if (head == null) return; 

    if (head.next == null) return; 
    Node curr = head;
    Node next = curr.Next;
    Node temp = next.Next;

    while (true)
    {
        temp = next.Next;
        next.Next = curr;
        curr.Next = temp;

        if  (curr.Next != null)
            curr = curr.Next;
        else
            break;
        if (curr.Next.Next!=null)
            next = curr.Next.Next;
        else
            break;
    }   
}

【问题讨论】:

  • 是的,我从那里收到了问题,但已经以我的方式实施了......想知道我是否可以在这里找到更好的解决方案
  • 没有人说使用额外的存储空间

标签: algorithm linked-list


【解决方案1】:

看看这个 C++ 解决方案:

public void exchangeAdjElements(){
    LLMain backup=current.next;
    LLMain temp = current.next;
    LLMain previous=current;
    while(current!=null && current.next!=null){
        previous.next=current.next;
        current.next=temp.next;
        temp.next=current;
        if(current.next!=null){
            previous=current;
            current=current.next;
            temp=current.next;
        }
    }
    current=backup;
}

这里的current是头节点。

【讨论】:

    【解决方案2】:

    这是一个简单得多的版本的粗略草图,假设 Node 有“Next”和“Data”成员:

      for (Node n = head; n && n.Next; n = n.Next.Next) {
        void* tmp = n.Data;
        n.Data = n.Next.Data;
        n.Next.Data = tmp;
      }
    

    换句话说,在列表中的每个其他节点处停止并将其数据与下一个(第一个)交换。很简单。

    编辑: 上述解决方案交换节点内的数据,而不是节点本身。如果要交换实际节点,则该解决方案需要更多逻辑。

    【讨论】:

    • 为什么要交换数据...节点必须交换...不是数据
    • 交换数据。?不。不。不。!你应该交换节点。
    • 它在“必须交换每 2 个备用链接”的问题中明确提及。但这个答案是交换数据而不是节点。
    【解决方案3】:

    @dkamins:你正在改变价值观,但在这类问题中,面试官通常会要求改组指针。

    My attempt for the problem:

    void swap (struct list **list1)
    {
        struct list *cur, *tmp, *next;
        cur = *list1;
    
        if(!cur || !cur->next)
                  return;
    
        *list1 = cur->next;
    
        while(cur && cur->next)
        {
                  next = cur->next;
                  cur->next = next->next;
                  tmp = cur->next;
                  next->next = cur;
                  if(tmp && tmp->next)
                      cur->next = cur->next->next;
                  cur = tmp;                                  
        }
    }
    

    【讨论】:

      【解决方案4】:

      这里是完全可运行的 Java。这纯粹是指针游戏。

      public class ListSwap {
          // the swap algorithm
          static void swap(Node current) {
              while (true) {
                  Node next1 = current.next;
                  if (next1 == null) break;
                  Node next2 = next1.next;
                  if (next2 == null) break;
                  Node next3 = next2.next;
                  current.next = next2;
                  next2.next = next1;
                  next1.next = next3;
                  current = next1;
              }
          }
          // the rest is infrastructure for testing
          static class Node {
              Node next;
              final char data; // final! Only pointer play allowed!
              Node(char data, Node next) {
                  this.data = data;
                  this.next = next;
              }
              @Override public String toString() {
                  return data + (next != null ? next.toString() : "");
              }
          }
      

      (继续...)

          static class List {
              Node head;
              List(String data) {
                  head = null;
                  String dataReversed = new StringBuilder(data).reverse().toString();
                  for (char ch : dataReversed.toCharArray()) {
                      head = new Node(ch, head);
                  }
                  head = new Node('@', head);
              }
              @Override public String toString() {
                  return head.toString();
              }
              void swapPairs() {
                  swap(head);
              }
          }
          public static void main(String[] args) {
              String data = "a1b2c3d4e5";
              for (int L = 0; L <= data.length(); L++) {
                  List list = new List(data.substring(0, L));
                  System.out.println(list);
                  list.swapPairs();
                  System.out.println(list);
              }
          }
      }
      

      (see full output)

      【讨论】:

        【解决方案5】:

        我在某种程度上改编了@dkamins 的解决方案。我没有接收指向指针的指针,而是返回新的head。我也加强了它。

        struct Node
        {
           struct Node *next;
           int data;
        };
        
        typedef struct Node * NodePtr;
        NodePtr swapEveryTwo(NodePtr head)
        {
           NodePtr newHead = (head && head->next) ? head->next : head;
           NodePtr n = head;
           while(n && n->next)
           {
              NodePtr tmp = n;     // save (1)
              n = n->next;         // (1) = (2)
              tmp->next = n->next; // point to the 3rd item
              n->next = tmp;       // (2) = saved (1)
              n = tmp->next;       // move to item 3
        
              // important if there will be further swaps
              if(n && n->next) tmp->next = n->next;
           }
        
           // return the new head
           return newHead;
        }
        

        基本上,如果NULL 或长度为 1,则列表的新头是当前头,或者是第二个元素。

        在交换循环中,tmp 最终将成为第二个元素,但最初它是第一个。因此,我们需要它指向第三个元素,这就是tmp-&gt;next = n-&gt;next; 的目的。我不使用for 循环,因为如果我们这样做了,它就不那么直观了——重新评估表达式每次迭代只会跳1 个节点。在while 循环的末尾,n = tmp-&gt;next; 具有直观意义 - 我们将其指向第二个元素 tmp 之后的元素。

        最重要的部分是最后一行。因为我们是向前做的,所以我们必须记住,前一次迭代的第 2 个元素几乎肯定会指向当前迭代的最终 4th 元素,因为这次迭代将交换 3 和 4 . 所以在迭代结束时,如果我们意识到我们将在下一次迭代中再次交换,我们悄悄地将第 2 个元素指向当前的第 4 个元素,知道下一次迭代它将是第 3 个元素并且一切正常.

        例如,如果列表是2 -&gt; 7 -&gt; 3 -&gt; 5

        n = 2
        tmp = 2
        n = 7
        tmp->next = 3 (2 -> 3)
        n->next = 2 (7 -> 2)
        n = 3
        7 -> 2 -> 3 -> 5
        
        but then there will be swaps, so the last statement says
        7 -> 2 -> 5      3?
        

        这没关系,因为 n = 3,所以我们没有丢失那个节点。下一次迭代:

        n = 3
        tmp = 3
        n = 5
        tmp->next = NULL (3 -> NULL)
        n->next = 3  (5 -> 3)
        n = NULL
        

        导致最终的7 -&gt; 2 -&gt; 5 -&gt; 3 答案。

        【讨论】:

          【解决方案6】:

          我想为了提高效率,最好在函数中使用另一个参数 n 。 此 n 用于 count ,即在需要更改多少个节点之后。在上述情况下 n = 2。 然后继续迭代,直到你点击 n 并使用反向链接列表算法或递归反向链接列表算法来完成。

          void ReverseLinkList(struct node* head, int n) { 如果(头==空||空

          struct node* start = head;
          struct node* next = null;
          struct node* end = head;
          
          int count = 1;
          
          while(end->next != null)
          {
              if(count == n)
              {
                  next = end->next;
                  count = 1;
                  //Use ReverseLinklist From start to end
                  end->next = next;
                  end = next;
                  start = next;
              }
              else
              {
                  end = end->next;
                  count++;
              }
          }
          

          }

          【讨论】:

            【解决方案7】:
            void SwapAdjacentNodes (Node head)
            {
                if (head == null) return; 
            
                if (head.next == null) return; 
                Node curr = head;
                Node next = curr.Next;
                Node temp = next.Next;
            
                while (true)
                {
                    temp = next.Next;
                    next.Next = curr;
                    curr.Next = temp;
            
                    if  (curr.Next != null)
                        curr = curr.Next;
                    else
                        break;
                    if (curr.Next.Next!=null)
                        next = curr.Next.Next;
                    else
                        break;
                }   
            }
            

            有用吗!?
            因为。
            说:

            1[cur] -> 2[next] -> 3 [temp]-> 4
            

            循环之后

            2 -> 1 -> 3[cur] -> 4[next] -> NULL [temp]
            

            然后。

            2 -> 1 -> 4 -> 3 ->  NULL
            

            这就是我们所期望的对吗?
            但你知道。实物会是这样的。

            2 -> (1,4) -> 3  -> NULL
            

            因为您没有将 1->next 链接更改为 4!它仍然指向 3!
            我的版本:Click here

            【讨论】:

              【解决方案8】:

              这是我的 C++ 代码:它将返回指向交换链表的指针

              Node* swap_list(Node* node) {
              if(node == NULL)
                  return NULL;
              
              Node* ret = node->next;
              Node* pre_a = NULL;
              Node* a = node;
              Node* b = node->next;   
              
              while(a!=NULL && b!=NULL) {     
                  a->next = b->next;
                  b->next = a;
                  if(pre_a!=NULL)
                      pre_a->next = b;
                  pre_a = a;
                  a = a->next;
                  if(a==NULL) break;
                  b = a->next;        
              }
              
              return ret;
              }
              

              【讨论】:

                【解决方案9】:

                私有静态 SList swapAlternateElements(SList n){

                    if(n == null)
                        return n;
                    SList head = swap(n);
                    SList tail = head;
                
                    while(tail == null || tail.next != null){
                        tail.next.next = swap(tail.next.next);
                        tail = tail.next.next;
                    }
                
                    return head;
                
                }
                
                private static SList swap(SList n){
                
                    if(n.next == null || n==null){
                        return n;
                    }
                    SList current = n.next;
                    SList next = current.next;
                    n.next = next;
                    current.next = n;
                    return current;
                
                }
                

                【讨论】:

                  【解决方案10】:

                  我试图解决它,这是解决方案。

                  public Node swapAdjacentNodes() {
                      if (head == null)
                          return null;
                      if (head.nextNode == null)
                          return head;
                      Node previous = null;
                      Node current = head;
                      Node next = head.nextNode;
                      while (next != null && next != current) {
                          current.nextNode = next.nextNode;
                          next.nextNode = current;
                          if (previous == null) {
                              previous = next;
                              head = previous;
                              previous = previous.nextNode;
                          } else {
                              previous.nextNode = next;
                              previous = previous.nextNode.nextNode;
                          }
                          current = current.nextNode;
                          if (current == null)
                              break;
                          next = next.nextNode.nextNode.nextNode;
                  
                      }
                      return head;
                  
                  }
                  

                  【讨论】:

                    【解决方案11】:

                    这是我的 C 函数,用于交换链表中备用节点的链接。我在代码中包含了 cmets。为了更好地理解,举个例子,用笔和纸制作图表来完成这些步骤。

                     void swap_alternate_nodes(struct node **head)
                        {
                            if(*head==NULL)
                                return;
                            if((*head)->next==NULL)
                                return;
                    
                            struct node *prev = *head;
                            struct node *curr = (*head)->next;
                            struct node *temp = NULL;
                            *head = (*head)->next; // new head will be second node
                            while(curr!=NULL && prev!=NULL)
                            {
                                if(temp!=NULL)
                                    temp->next = curr; // previous prev node pointer should point to curr pointer
                    
                                prev->next = curr->next; // update prev node pointer
                    
                                curr->next = prev; // update curr node pointer
                    
                                temp = prev; //store prev pointer
                    
                                prev = prev->next; // forward prev pointer
                    
                                if(prev)
                                    curr = prev->next; // forward curr pointer
                            }
                        }
                    

                    【讨论】:

                      【解决方案12】:

                      我对解决方案的看法:-

                      public Node exchangeAdjacentNodes(Node head){
                           Node curr = head;
                           Node temp=null,next=null;
                           if(curr==null||curr.next==null){
                               return curr;
                           Node head = curr.next;
                           while(curr!=null && curr.next!=null){
                                 next = curr.next;
                                 curr.next=next.next;
                                 temp = curr.next;
                                 next.next = curr;
                                 if(temp!=null && temp.next!=null)
                                       curr.next = curr.next.next;
                                 curr=temp;
                            }
                            return head;
                      }
                      

                      【讨论】:

                        【解决方案13】:

                        这里,'head' 是指向链表第一个节点的指针,函数返回新的头指针。

                        node* swapPairs(node *head) {
                        if(head==NULL || head->next==NULL) {
                            return head;
                        }
                        
                        node *ptr1=head->next;
                        node *ptr2=ptr1->next;
                        ptr1->next=head;
                        head->next=swapPairs(ptr2);
                        return ptr1;
                        

                        }

                        【讨论】:

                          【解决方案14】:
                          public void swapAdjacent() {
                              temp = head;
                              while (temp != null && temp.next != null) {
                                  Object tem = temp.val;
                                  temp.val = temp.next.val;
                                  temp.next.val = (Object) tem;
                                  temp = temp.next.next;
                              }
                          }
                          

                          【讨论】:

                            【解决方案15】:

                            这可能会有所帮助: 公共静态 void main(String[] args) {

                                String arr[] = { "a", "b", "c", "d", "e", "f" };
                                int i = 0;
                                int k = 1;
                                String temp;
                            
                                while (k <= arr.length - 1 && arr[i] != null && arr[k] != null) {
                            
                                    temp = arr[i];
                                    arr[i] = arr[k];
                                    arr[k] = temp;
                            
                                    k++;
                                    i = k;
                                    k++;
                                }
                                for (int j = 0; j < arr.length; j++) {
                            
                                    System.out.print(arr[j]+"->");
                                }
                            
                            }
                            // Input  ->  a->b->c->d->e->f->
                            // Output -> b->a->d->c->f->e->
                            

                            【讨论】:

                              【解决方案16】:

                              交换相邻的 C 代码

                              node *SwapAdjacent(node *root)
                              {
                                  *NextNode = NULL;
                                  node * result = root->next;
                                  node *prev = NULL;
                                  while (root != NULL && root->next!=NULL)
                                  {
                                      if(prev!=NULL)
                                          prev->next= root->next;
                                      NextNode = root->next->next;
                                      root->next->next = root;
                                      root->next = NextNode;
                                      prev = root;
                                      root = NextNode;
                                  }
                                  return result;
                              }
                              

                              【讨论】:

                                猜你喜欢
                                • 1970-01-01
                                • 1970-01-01
                                • 2012-01-25
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                相关资源
                                最近更新 更多