• Careercup | Chapter 2


    链表的题里面,快慢指针、双指针用得很多。

    2.1 Write code to remove duplicates from an unsorted linked list.
    FOLLOW UP
    How would you solve this problem if a temporary buffer is not allowed?

    2.2 Implement an algorithm to find the kth to last element of a singly linked list.

    2.3 Implement an algorithm to delete a node in the middle of a singly linked list, given only access to that node.

    2.4 Write code to partition a linked list around a value x, such that all nodes less than x come before alt nodes greater than or equal to x.

    Leetcode上有,点

    2.5 You have two numbers represented by a linked list, where each node contains a single digit. The digits are stored in reverse order, such that the 1 's digit is at the head of the list. Write a function that adds the two numbers and returns the sum as a linked list.

    Leetcode上有,点
    FOLLOW UP
    Suppose the digits are stored in forward order. Repeat the above problem.

    reverse之后求后然后再reverse结果,careercup上的做法更inefficient。

     2.6 Given a circular linked list, implement an algorithm which returns the node at the beginning of the loop.

    Leetcode上有,点

    2.7 Implement a function to check if a linked list is a palindrome,

    naive的方法就是把list reverse一下,然后和原串比较。

    更好的方法是用stack,比较前半部分还是很巧妙的。stack用来reverse也是比较直观的。注意奇偶长度的list。

    递归的方法理解起来更难些。传递指针的指针,使得递归调用后,指针move到对应的镜像位置上了。这一点和Leetcode上Convert Sorted List to Binary Search Tree类似。

      1 struct ListNode {
      2     int val;
      3     ListNode* next;
      4     ListNode(int v) : val(v), next(NULL) {}
      5 };
      6 
      7 class XList {
      8 public:
      9     XList(int n) {
     10         srand(time(NULL));
     11         head = NULL;
     12         for (int i = 0; i < n; ++i) {
     13             ListNode* next = new ListNode(rand() % 1000);
     14             next->next = head;
     15             head = next;
     16         }
     17         len = n;
     18     }
     19 
     20     XList(XList &copy) {
     21         //cout << "copy construct" << endl;
     22         len = copy.size();
     23         if (len == 0) return;
     24         head = new ListNode(copy.head->val);
     25         ListNode *p = copy.head->next, * tail = head;
     26 
     27         while (p != NULL) {
     28             tail->next = new ListNode(p->val);
     29             tail = tail->next;
     30             p = p->next;    
     31         }
     32     }
     33 
     34     ~XList() {
     35         ListNode *tmp = NULL;
     36 
     37         while (head != NULL) {
     38             tmp = head->next;
     39             delete head;
     40             head = tmp;
     41         }
     42     }
     43 
     44     // 2.1(1)
     45     void removeDups() {
     46         if (head == NULL) return;
     47         map<int, bool> existed;
     48         ListNode* p = head, *pre = NULL;
     49         while (p != NULL) {
     50             if (existed[p->val]) {
     51                 pre->next = p->next;
     52                 len--;
     53                 delete p;
     54                 p = pre->next;
     55             } else {
     56                 pre = p;
     57                 existed[p->val] = true;
     58                 p = p->next;
     59             }
     60         }
     61     }
     62 
     63     //2.1(2)
     64     void removeDups2() {
     65         ListNode *p = head;
     66 
     67         while (p != NULL) {
     68             ListNode *next = p;
     69             while (next->next) {
     70                 if (next->next->val == p->val) {
     71                     ListNode *tmp = next->next;
     72                     len--;
     73                     delete next->next;
     74                     next->next = tmp->next;
     75                 } else { 
     76                     next = next->next; // only move to next in the 'else' block
     77                 }
     78             }
     79             p = p->next;
     80         }
     81     }
     82 
     83     // 2.2(1)
     84     ListNode* findKthToLast(int k) {
     85         if (head == NULL) return NULL;
     86         if (k <= 0) return NULL; // more efficient
     87         ListNode *fast = head, *slow = head;
     88         int i = 0;
     89         for (; i < k && fast; ++i) {
     90             fast = fast->next;
     91         }
     92         if (i < k) return NULL;
     93         while (fast) {
     94             slow = slow->next;
     95             fast = fast->next;
     96         }
     97         return slow;
     98     }
     99     
    100     //2.2(2)
    101     ListNode* findKthToLast2(int k) {
    102         return recursiveFindKthToLast(head, k);
    103     }
    104 
    105     //2.2(2)
    106     ListNode* recursiveFindKthToLast(ListNode *h, int &k) {
    107         if (h == NULL) {
    108             return NULL;
    109         }
    110     
    111         // should go to the end
    112         ListNode *ret = recursiveFindKthToLast(h->next, k);
    113         k--; 
    114         if (k == 0) return h;
    115         return ret;
    116     }
    117 
    118     // 2.3
    119     bool deleteNode(ListNode* node) {
    120         if (node == NULL || node->next == NULL) return false; // in the middle, head is also ok, because we don't delete node itself
    121 
    122         ListNode *next = node->next;
    123         node->val = next->val;
    124         node->next = next->next;
    125         len--;
    126         delete next;
    127         return true;
    128     }
    129 
    130     // 2.4
    131     void partition(int x) {
    132         if (head == NULL) return;
    133         ListNode less(0), greater(0);
    134         ListNode* p = head, *p1 = &less, *p2 = &greater;
    135 
    136         while (p) {
    137             if (p->val < x) {
    138                 p1->next = p;
    139                 p1 = p1->next;
    140             } else {
    141                 p2->next = p;
    142                 p2 = p2->next;
    143             }
    144             p = p->next;
    145         }
    146 
    147         p1->next = greater.next;
    148         head = less.next;
    149     }
    150 
    151     // 2.7(1)
    152     bool isPalindrome() {
    153         if (head == NULL) return true;
    154         stack<ListNode*> st;
    155         ListNode *fast = head, *slow = head;
    156         while (fast && fast->next) {
    157             st.push(slow);
    158             slow = slow->next;
    159             fast = fast->next->next;
    160         }
    161     
    162         if (fast) slow = slow->next; // fast->next = null, odd number, skip the middle one
    163 
    164         while (slow) {
    165             if (slow->val != st.top()->val) return false;
    166             slow = slow->next;
    167             st.pop();
    168         }
    169 
    170         return true;
    171     }
    172 
    173     // 2.7(2)
    174     bool isPalindrome2() {
    175         ListNode* h = head;
    176         return recursiveIsPalindrome(h, len);
    177     }
    178 
    179     bool recursiveIsPalindrome(ListNode* &h, int l) { // note that h is passed by reference
    180         if (l <= 0) return true;
    181         if (l == 1) {
    182             h = h->next; // move, when odd
    183             return true;
    184         }
    185         if (h == NULL) return true;
    186         int v1 = h->val;
    187         h = h->next;
    188         if (!recursiveIsPalindrome(h, l - 2)) return false;
    189         int v2 = h->val;
    190         h = h->next;
    191         cout << v1 << " vs. " << v2 << endl;
    192         return v1 == v2;
    193     }
    194 
    195     void print() const {
    196         ListNode *p = head;
    197         while (p != NULL) {
    198             cout << p->val << "->";
    199             p = p->next;
    200         }
    201         cout << "NULL(len: " << len << ")" << endl;
    202     }
    203 
    204     int size() const {
    205         return len;
    206     }
    207 
    208     void insert(int v) {
    209         len++;
    210         ListNode *node = new ListNode(v);
    211         node->next = head;
    212         head = node;
    213     }
    214 private:
    215     ListNode *head;
    216     int len;
    217 };
  • 相关阅读:
    linux 环境变量恢复默认值
    怎么查看Eclipse的版本信息
    掌握HDFS的Java API接口访问
    【代理】代理概念
    【DbUtils】轻量级的ORM学习
    【mysql】相关记录
    JWT(JSON Web Tokens)
    将jar包安装到本地仓库
    Spring集成rabbitmq
    spring-rabbit包的引入需要注意的事项
  • 原文地址:https://www.cnblogs.com/linyx/p/3777817.html
Copyright © 2020-2023  润新知