struct ListNode* reverseList(struct ListNode* head) {
struct ListNode* prev = NULL;
struct ListNode* curr = head;
struct ListNode* next = NULL;
while(curr)
{
next = curr->next; //save next
curr->next = prev; //reverse
if (next==NULL){ //last node of list
break;
}
prev = curr; //move forword
curr = next; //move forword
}
return curr;
}
struct ListNode* reverseKGroup(struct ListNode* head, int k) {
struct ListNode* kTail = head; //k个节点的尾节点
struct ListNode* nextHead = NULL;//下一组k个节点的头节点
int n = k-1;
while(n-- && kTail){
kTail = kTail->next;
}
if (kTail){
nextHead = kTail->next;
}
if (kTail){ //满足k个节点即可反转
struct ListNode* oldHead = head; //保存下旧的头部
struct ListNode* prev = NULL;
struct ListNode* curr = head;
struct ListNode* next = NULL;
while(curr){
next = curr->next;
curr->next = prev;
if(next == nextHead){ //翻转到下一组的头节点就截止
break;
}
prev = curr;
curr = next;
}
oldHead->next = reverseKGroup(next, k); //旧的头节点(即翻转后的尾节点)指向下一组的头节点
return curr; //返回翻转后新的head
}
return head; //不满足k个节点则直接返回 head
}
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2) {
if (l1 == NULL || l2 == NULL)
return l1 != NULL? l1 : l2;
struct ListNode head = {0, NULL}; //virtual head node
struct ListNode *tail = &head;
while(l1 && l2){
if (l1->val < l2->val){
tail->next = l1;
l1=l1->next;
}else{
tail->next = l2;
l2=l2->next;
}
tail=tail->next;
}
tail->next = l1==NULL ? l2:l1;
return head.next;
}
//找到K个链表中最小的头节点
struct ListNode* findMinNode(struct ListNode** lists, int listsSize, int*index)
{
int init=0;
struct ListNode* min = NULL;
for (int i=0;i<listsSize;i++){
if (lists[i]==NULL)
continue;
if (init==0){ //初始化第一个最小节点
min=lists[i];
*index = i;
init=1;
} else {
if (lists[i]->val < min->val){
*index = i;
min=lists[i];
}
}
}
return min;
}
struct ListNode* mergeKLists(struct ListNode** lists, int listsSize) {
struct ListNode head = {0, NULL};
struct ListNode* tail = &head;
struct ListNode* minNode = NULL;
int i = 0;
while(minNode = findMinNode(lists, listsSize, &i)){
tail->next = minNode;
tail = tail->next;
lists[i] = lists[i]->next;
}
return head.next;
}
bool hasCycle(struct ListNode *head) {
struct ListNode *slow = head;
struct ListNode *fast = head;
while(slow && fast && fast->next){
slow = slow->next;
fast = fast->next->next;
if (fast == slow)
return true;
}
return false;
}
struct ListNode *detectCycle(struct ListNode *head) {
struct ListNode *slow = head;
struct ListNode *fast = head;
struct ListNode *meet = NULL;
//find meet node
while(slow && fast && fast->next){
slow = slow->next;
fast = fast->next->next;
if (slow==fast){
meet = slow;
break;
}
}
slow = head;
while(slow && meet){
if (meet==slow){ //find entry point
return meet;
}
slow = slow->next;
meet = meet->next;
}
return NULL;
}
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
struct ListNode* slow = head;
struct ListNode* fast = head;
while(fast && n--){
fast=fast->next;
}
while(slow && fast && fast->next){
slow = slow->next;
fast = fast->next;
}
if (fast==NULL){ //删除的是第一个节点
head = head->next;
}else if (slow && slow->next){ //删除的不是第一个节点
slow->next = slow->next->next;
}
return head;
}
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
if (headA==NULL || headB==NULL){
return NULL;
}
//先找到其中一个链表的尾节点
struct ListNode *tailA = headA;
while(tailA->next){
tailA = tailA->next;
}
//将尾节点和头结点连起来形成环
tailA->next = headA;
//问题转化为求环的入口
struct ListNode *slow = headB;
struct ListNode *fast = headB;
struct ListNode *meet = NULL;
while(slow && fast && fast->next){
slow = slow->next;
fast = fast->next->next;
if (slow==fast){
meet = slow;
break;
}
}
slow = headB;
while(slow && meet){
if (slow==meet){
break;
}
slow = slow->next;
meet = meet->next;
}
将尾节点和头结点解开
tailA->next = NULL;
return meet;
}
struct ListNode* removeElements(struct ListNode* head, int val) {
//移除最开始相等的节点,直到第一个不相等的
while(head && head->val == val){
head = head->next;
}
//head 一定是不相等的节点,此时如果下一个节点为空可以直接返回了
if (head==NULL || head->next==NULL)
return head;
//2个指针一前一后
struct ListNode* slow = head;
struct ListNode* fast = head->next;
while(slow && fast){
if (fast->val==val){ //快指针相等的话,慢指针直接删除该节点
slow->next = fast->next;
}else{
slow = slow->next;
}
fast = fast->next;
}
return head;
}
以下面2个链表为例
list1: 1->2->3->2->1
list2: 1->2->3->2
struct ListNode* reverse(struct ListNode* head, struct ListNode* givenNode){
struct ListNode* prev = NULL;
struct ListNode* curr = head;
struct ListNode* next = NULL;
while(curr){
next = curr->next;
curr->next = prev;
if (next == givenNode){
break;
}
prev = curr;
curr = next;
}
return curr;
}
bool isPalindrome(struct ListNode* head) {
//1个节点
if (head && head->next==NULL){
return true;
}
//2个节点
if (head && head->next && head->next->next==NULL){
if (head->val == head->next->val){
return true;
}else{
return false;
}
}
struct ListNode* slow = head;
struct ListNode* fast = head;
while (slow!=NULL && fast!=NULL && fast->next!=NULL) {
slow = slow->next;
fast = fast->next->next;
}
struct ListNode* left = reverse(head, slow);
struct ListNode* right = NULL;
if (fast){ //奇数链表
right = slow->next;
}else{ //偶数链表,此时slow指向第len/2+1个节点
right = slow;
}
while(left && right){
if (left->val != right->val){
return false;
}else{
left = left->next;
right = right->next;
}
}
return true;
}
struct ListNode* oddEvenList(struct ListNode* head) {
if (head==NULL || head->next==NULL)
return head;
struct ListNode* oddHead = head; //奇数节点的头
struct ListNode* oddTail = oddHead; //奇数节点的尾
struct ListNode* eventHead = head->next; //偶数节点头
struct ListNode* eventTail = eventHead; //偶数节点尾
bool isOdd = true;
head = head->next->next; //从第3个节点开始
while(head){
printf("%d\n", head->val);
if (isOdd){
oddTail->next = head;
oddTail = oddTail->next;
isOdd = false;
}else{
eventTail->next = head;
eventTail = eventTail->next;
isOdd = true;
}
head = head->next;
}
if (!isOdd) //一定要将偶数节点的最后一个节点置为空
eventTail->next = NULL;
oddTail->next = eventHead;
return oddHead;
}
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
struct ListNode*newNode(int val)
{
struct ListNode* node = malloc(sizeof(struct ListNode));
node->val = val;
node->next = NULL;
return node;
}
struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2) {
struct ListNode head = {0,NULL};
struct ListNode* tail = &head;
struct ListNode* p1 = l1;
struct ListNode* p2 = l2;
int carry = 0; //进位
while(p1 && p2){
int sum = p1->val + p2->val + carry;
carry = sum/10;
tail->next = newNode(sum%10);
tail = tail->next;
p1 = p1->next;
p2 = p2->next;
}
if (carry != 0){
while(p1){
int sum = p1->val + carry;
carry = sum/10;
tail->next = newNode(sum%10);
tail = tail->next;
p1 = p1->next;
}
while(p2){
int sum = p2->val + carry;
carry = sum/10;
tail->next = newNode(sum%10);
tail = tail->next;
p2 = p2->next;
}
if (carry!=0){
tail->next = newNode(carry);
tail = tail->next;
}
}else{
tail->next = p1==NULL?p2:p1;
}
return head.next;
}
struct ListNode* rotateRight(struct ListNode* head, int k) {
if (head==NULL || k<=0)
return head;
struct ListNode* slow = head;
struct ListNode* fast = head;
while(k--){
fast = fast->next;
if(fast == NULL){ //k>len 的时候从头开始
fast = head;
}
}
if (slow==fast){ // 相等表示 k%len==0
return head;
}
while(slow && fast && fast->next){
fast = fast->next;
slow = slow->next;
}
struct ListNode* newHead = slow->next;
slow->next = NULL;
fast->next = head;
return newHead;
}