一. 合并两个升序单链表
把两个单链表,按升序排列为一个单链表。
看到就想到的思路
1)看首链表谁小,作为一个首地址存了,假设为l1;
2)遍历另一个链表l2,比较其是否在l1的第一和第二结点值区间里;
3)在,就插入;不在,比较l1的第二个和第三个结点值区间,依次类推;
4)l1或l2遍历完了,就连起来。返回第一步存的首地址。
例如:[1->3]->5->7 和2->2->3->4->6
问题
1)写起来的时候,感觉很麻烦
2)你知道了链表l2在l1的第一和第二区间里,这相当于内部插入,内部插入,你l2的结点要指向l1的第二个结点,l1第一个指向l2结点,l2结点的下一个next也要被保存下来。很麻烦。
参考思路:尾插
1)看首链表谁小,作为一个首地址存了,假设为l1;
2)比较l1的第二个结点和l2的第一个结点,谁小,尾插在1)的首结点后。
3)看l1和l2谁先走完,最后连起来。
增益点
1.能头插,尾插,就不要想中间插入
现在回看,我没必要把l2的结点和l1的第二个结点连起来,多此一举。但为什么我会最先想到这种思路呢?我是先以一个链表为参考,把另一个链表打碎放入这个参考链表里。这反而禁锢了。
2.尾插,哨兵结点
无头结点:开始为NULL的结点
哨兵结点:自己开辟的一块不存储有效数据的结点
哨兵结点更容易尾插,更容易找到首链表的地址,也就是起始地址,这方便的多。
无头结点,你需要比较l1和l2的首结点谁小,再作为起始地址,麻烦些。
代码:无头结点
无头结点还需要把头存起来啊,麻烦了
mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {Node* n1 = list1;Node* n2 = list2;Node* store = NULL;Node* n3 = NULL;if (n1->val >= n2->val){store = n2;n2 = n2->next;}else{store = n1;n1 = n1->next;}n3 = store; 这里无头结点还需要把头存起来啊,麻烦了while (n1 && n2){if (n1->val > n2->val){n3->next = n2;n2 = n2->next;}else{n3->next = n1;n1 = n1->next;}n3 = n3->next;}if (n1 == NULL)n3->next = n2;elsen3->next = n1;return store;
}
二. 以某个值为界限,重排链表
小于x放链表前面,大于等于的放后面。
刚看到的思路
1)哨兵结点,找大的,尾插
2)哨兵结点,找小的,尾插
3)小连大
和参考思路一致,但是一直有一个超时的错误
增益点:防止环,next指向常设NULL
这里的尾插在最后
1)small的next是指向big链表的
2)但是big的最后结点是指向small的最后一部分结点的,相当于成一个环路了。
3)small指向big,big又指向small最后一部分结点,相当于big一直在循环
代码
超时错误的原因是,少了big->next=NULL;,导致链表成环,无限循环
typedef struct ListNode Node;
struct ListNode* partition(struct ListNode* head, int x) {Node* small=(Node*)malloc(sizeof(Node));Node* smallstore=small;Node* big=(Node*)malloc(sizeof(Node));Node* bigstore=big;Node* cur=head;if (head == NULL)return head;while(cur){if(cur->val<x){small->next=cur;cur=cur->next;small=small->next;}else{big->next=cur;cur=cur->next;big=big->next;}}big->next=NULL;-----------------超时原因small->next=bigstore->next;return smallstore->next;}
三. 数组有两个元素出现一次,其余都出现两次
找出现一次的这两个元素。难嘞,加减不行,异或不行。
参考思路
1)异或,得到两个元素的异或值
(难不成你还能分离出这两个元素不成?)
2)异或的特点,某个位是1,则x1的这个位和x2的这个位不同,分别为0和1
3)找出第M位为1的组,和M位为0的组。
4)两组各自做异或,找出单独的两个元素。这样就成数组有一个元素出现一次,其余出现两次了。
用处不大的增益点:位
对位的操作可能会使解题更加便捷。谁想到到?这里的看第M位是否为1,再进行分组。