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 };

 

你可能感兴趣的:(apt)