在已排序的单链表中查找和为给定值的一对数 (C++)


假设我们有一个单链表和一个值 x;我们需要找到一对节点,其值的和等于 x。需要注意的是,我们不能使用额外的空间,并且期望的时间复杂度为 O(n)。

例如,如果输入是 4→7→8→9→10→11→12,x = 19,则输出将是 [(7, 12), (8, 11), (9, 10)]

为了解决这个问题,我们将遵循以下步骤:

  • 定义一个函数 `convert_to_xor()`,它将接收起始节点作为参数。

  • `prev := NULL`

  • 当 `start` 不为 NULL 时,执行以下操作:

    • `next_list_node := start 的下一个节点`

    • `start 的下一个节点 := next_list_node 的地址与 prev 地址的异或`

    • `prev := start`

    • `start := next_list_node`

  • 在主方法中,执行以下操作:

  • `first := start`

  • `next_list_node := NULL, prev := NULL, second := start`

  • 当 `second` 的下一个节点不等于 `prev` 时,执行以下操作:

    • `temp := second`

    • `second := (second 的下一个节点的地址) 与 (prev 地址) 的异或`

    • `prev := temp`

  • `next_list_node := NULL`

  • `prev := NULL`

  • `flag := false`

  • 当 (first 不等于 NULL 且 second 不等于 NULL 且 first 不等于 second 且 first 不等于 next_list_node) 时,执行以下操作:

    • 如果 first 的数据 + second 的数据等于 x,则:

      • 显示 first 的数据和 second 的数据

      • `flag := true`

      • `temp := first`

      • `first := (first 的下一个节点的地址) 与 (prev 地址) 的异或`

      • `prev := temp`

      • `temp := second`

      • `second := (second 的下一个节点的地址) 与 (next_list_node 地址) 的异或`

      • `next_list_node := temp`

    • 否则

      • 如果 first 的数据 + second 的数据 < x,则

        • `temp := first`

        • `first := (first 的下一个节点的地址) 与 (prev 地址) 的异或`

        • `prev := temp`

      • 否则

        • `temp := second`

        • `second := (second 的下一个节点的地址) 与 (next_list_node 地址) 的异或`

        • `next_list_node := temp`

  • 如果 flag 为 false,则:

    • 没有找到这样的数对

示例 (C++)

让我们来看下面的实现,以便更好地理解:

 在线演示

#include<bits/stdc++.h>
using namespace std;
class ListNode {
public:
   int data;
   ListNode *next;
   ListNode(int data) {
      this->data = data;
      next = NULL;
   }
};
ListNode *make_list(vector<int> v) {
   ListNode *start = new ListNode(v[0]);
   for (int i = 1; i < v.size(); i++) {
      ListNode *ptr = start;
      while (ptr->next != NULL) {
         ptr = ptr->next;
      }
      ptr->next = new ListNode(v[i]);
   }
   return start;
}
ListNode* XOR (ListNode *a, ListNode *b) {
   return (ListNode*) ((uintptr_t) (a) ^ (uintptr_t) (b));
}
void convert_to_xor(ListNode *start) {
   ListNode *next_list_node;
   ListNode *prev = NULL;
   while (start != NULL) {
      next_list_node = start->next;
      start->next = XOR(next_list_node, prev);
      prev = start;
      start = next_list_node;
   }
}
void get_pared_sum(ListNode *start, int x) {
   ListNode *first = start;
   ListNode *next_list_node = NULL, *prev = NULL;
   ListNode *second = start;
   while (second->next != prev) {
      ListNode *temp = second;
      second = XOR(second->next, prev);
      prev = temp;
   }
   next_list_node = NULL;
   prev = NULL;
   bool flag = false;
   while (first != NULL && second != NULL && first != second && first != next_list_node) {
      if ((first->data + second->data)==x) {
         cout << "(" << first->data << ","<< second->data << ")" << endl;
         flag = true;
         ListNode *temp = first;
         first = XOR(first->next,prev);
         prev = temp;
         temp = second;
         second = XOR(second->next, next_list_node);
         next_list_node = temp;
      }
      else{
         if ((first->data + second->data) < x) {
            ListNode *temp = first;
            first = XOR(first->next,prev);
            prev = temp;
         }
         else{
            ListNode *temp = second;
            second = XOR(second->next, next_list_node);
            next_list_node = temp;
         }
      }
   }
   if (flag == false)
      cout << "No pair found" << endl;
}
int main() {
   vector<int> v = {4,7,8,9,10,11,12};
   ListNode* start = make_list(v);
   int x = 19;
   convert_to_xor(start);
   get_pared_sum(start,x);
}

输入

{4,7,8,9,10,11,12}

输出

(7,12) (8,11) (9,10)

更新于:2020-08-25

110 次浏览

开启你的职业生涯

完成课程获得认证

开始学习
广告