【leetcode算法面试】leetcode题目7-链表

 

题号题目说明
2Add Two Numbers 两个数字相加低位在表头
19Remove Nth Node From End of List 移除链表倒数第N个节点 
21Merge Two Sorted Lists   混合插入有序链表 
23

Merge k Sorted Lists 合并k个有序链表

递归 / 非递归
24Swap Nodes in Pairs 成对交换节点递归 / 非递归
25

Reverse Nodes in k-Group 每k个一组翻转链表

 
61Rotate List 旋转链表 
83Remove Duplicates from Sorted List 移除有序链表中的重复项 
147Insertion Sort List 链表插入排序 
148Sort List 链表排序递归分治
206Reverse Linked List 倒置链表 

 

2. Add Two Numbers 两个数字相加

    建立一个新链表,然后把输入的两个链表从头往后,每两个相加,添加一个新节点到新链表后面

func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
	var head = &ListNode{}
	var cur = head
	var carry = 0
	for l1 != nil || l2 != nil {
		var l1Val, l2Val = 0, 0
		if l1 != nil {
			l1Val = l1.Val
			l1 = l1.Next
		}
		if l2 != nil {
			l2Val = l2.Val
			l2 = l2.Next
		}
		var sum = l1Val + l2Val + carry
		carry = sum / 10
		cur.Next = &ListNode{Val: sum % 10}
		cur = cur.Next
	}
	if carry > 0 {
		cur.Next = &ListNode{Val: carry}
	}
	return head.Next
}

 

19. Remove Nth Node From End of List 移除链表倒数第N个节点

       首先要考虑的时,如何找到倒数第N个节点,pre和cur指针。首先cur指针先向前走N步,如果此时cur指向空,说明N为链表的长度,则需要移除的为首元素,那么此时我们返回head->next即可,如果cur存在,我们再继续往下走,此时pre指针也跟着走,直到cur为最后一个元素时停止,此时pre指向要移除元素的前一个元素

func removeNthFromEnd(head *ListNode, n int) *ListNode {
	if head == nil || n <= 0 {
		return nil
	}

	var dummpy = &ListNode{-1, head}

	var cur, pre = dummpy, dummpy
	for i := 0; i < n; i++ {
		cur = cur.Next
		if i != n-1 && cur == nil {
			return head
		}
	}
	for cur.Next != nil {
		cur = cur.Next
		pre = pre.Next
	}

	pre.Next = pre.Next.Next
	return dummpy.Next
}

 

21. [LeetCode] Merge Two Sorted Lists   混合插入有序链表

       定义一个新链表,头结点,用于返回;当前节点用于对链表元素赋值以及跳转到下一个节点

func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode {
	var dummpy = &ListNode{-1, nil}
	var cur = dummpy
	for l1 != nil && l2 != nil {
		if l1.Val < l2.Val {
			cur.Next = l1
			l1 = l1.Next
		} else {
			cur.Next = l2
			l2 = l2.Next
		}
		cur = cur.Next
	}

	if l1 != nil {
		cur.Next = l1
	}
	if l2 != nil {
		cur.Next = l2
	}
	return dummpy.Next
}

     递归法:

func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode {
	if l1 == nil {
		return l2
	}
	if l2 == nil {
		return l1
	}
	if l1.Val < l2.Val {
		l1.Next = mergeTwoLists(l1.Next, l2)
		return l1
	} else {
		l2.Next = mergeTwoLists(l1, l2.Next)
		return l2
	}
}

 

23. [LeetCode] Merge k Sorted Lists

    合并k个有序链表

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

      增加了难度,变成合并k个有序链表了,但是不管合并几个,基本还是要两两合并。分治法 Divide and Conquer Approach。简单来说就是不停的对半划分,比如k个链表先划分为合并两个k/2个链表的任务,再不停的往下划分,直到划分成只有一个或两个链表的任务,开始合并。

 

24. [LeetCode] Swap Nodes in Pairs 成对交换节点

     迭代法

func swapPairs(head *ListNode) *ListNode {
	var dummpy = &ListNode{-1, head}
	var cur = dummpy

	for cur.Next != nil && cur.Next.Next != nil {
		var t = cur.Next.Next
		cur.Next.Next = t.Next
		t.Next = cur.Next
		cur.Next = t
		cur = t.Next
	}

	return dummpy.Next
}

     递归遍历到链表末尾,然后先交换末尾两个,然后依次往前交换:

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if (!head || !head->next) return head;
        ListNode *t = head->next;
        head->next = swapPairs(head->next->next);
        t->next = head;
        return t;
    }
};

func swapPairs(head *ListNode) *ListNode {
	if head == nil || head.Next == nil {
		return head
	}
	var t = head.Next
	head.Next = swapPairs(head.Next.Next)
	t.Next = head
	return t
}

 

25. [LeetCode] Reverse Nodes in k-Group 每k个一组翻转链表

class Solution {
public:
    ListNode *reverseKGroup(ListNode *head, int k) {
        if (head==NULL || head->next==NULL || k<=1) return head;
        
        ListNode preHead(-1);
        preHead.next = head;
        ListNode *pre = &preHead;
        ListNode *pTemp;
        
        while (head != NULL) {
            ListNode *pEnd = head;
            for (int i=1; i<k && head!=NULL; i++) {
                head = head->next;
            }
            if (head == NULL) return preHead.next;
            
			pTemp = pEnd->next;
            for (int i=1; i<k; i++) {
                ListNode *pNext = pTemp->next;
                pTemp->next = pre->next;
                pre->next = pTemp;
                pTemp = pNext;
            }
            pre = pEnd;
            pEnd->next = pTemp;
            head = pTemp;
        }
        
        return preHead.next;
    }
};

 

61. [LeetCode] Rotate List 旋转链表

class Solution {
public:
    ListNode *rotateRight(ListNode *head, int k) {
        if (head==NULL || head->next==NULL || k<=0) return head;
        
        ListNode *pPre = head;
        ListNode *pTemp;
        int len = 0;
        
        while (pPre != NULL) {
            len++;
            pTemp = pPre;
            pPre = pPre->next;
        }
        
        k = len - k%len;
        pTemp->next = head;
        for (int i=0; i<k; i++) {
            pTemp = pTemp->next;
            head = head->next;
        }
        pTemp->next = NULL;
        
        return head;
    }
};

 

82. [LeetCode] Remove Duplicates from Sorted List II

    移除有序链表中的重复项之二

Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list.

Example 1:

Input: 1->2->3->3->4->4->5
Output: 1->2->5

Example 2:

Input: 1->1->1->2->3
Output: 2->3

        定义一个新的节点,然后链上原链表,然后定义一个前驱指针和一个现指针,每当前驱指针指向新建的节点,现指针从下一个位置开始往下遍历,遇到相同的则继续往下,直到遇到不同项时,把前驱指针的next指向下面那个不同的元素。如果现指针遍历的第一个元素就不相同,则把前驱指针向下移一位

class Solution {
public:
    ListNode *deleteDuplicates(ListNode *head) {
        if (!head || !head->next) return head;
        ListNode *dummy = new ListNode(-1), *pre = dummy;
        dummy->next = head;
        while (pre->next) {
            ListNode *cur = pre->next;
            while (cur->next && cur->next->val == cur->val) {
                cur = cur->next;
            }
            if (cur != pre->next) pre->next = cur->next;
            else pre = pre->next;
        }
        return dummy->next;
    }
};

 

83. [LeetCode] Remove Duplicates from Sorted List 移除有序链表中的重复项

Given a sorted linked list, delete all duplicates such that each element appear only once.

Example 1:

Input: 1->1->2
Output: 1->2

Example 2:

Input: 1->1->2->3->3
Output: 1->2->3

       遍历这个链表,每个结点和其后面的结点比较,如果结点值相同了,我们只要将前面结点的next指针跳过紧挨着的相同值的结点,指向后面一个结点

class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        ListNode *cur = head;
        while (cur && cur->next) {
            if (cur->val == cur->next->val) {
                cur->next = cur->next->next;
            } else {
                cur = cur->next;
            }
        }
        return head;
    }
};
class Solution {
public:
    ListNode *deleteDuplicates(ListNode *head) {
        if (head==NULL || head->next==NULL) return head;
        
        ListNode *pCur, *pNext;
        for (pCur=head, pNext=pCur->next; pNext!=NULL; ) {
            if (pCur->val == pNext->val) {
                pCur->next = pNext->next;
            }
            else {
                pCur = pNext;
            }
            
            pNext = pNext->next;
        }
        
        return head;
    }
};

 

147. Insertion Sort List 链表插入排序

func insertionSortList(head *ListNode) *ListNode {
	if head == nil || head.Next == nil {return head}
	var dummpy = &ListNode{Val: -1, Next: head}
	var cur = head.Next
	head.Next = nil
	head = cur
	for head != nil {
		var temp = head.Next
		cur = dummpy
		for cur.Next!=nil && cur.Next.Val <= head.Val {
			cur = cur.Next
		}
		head.Next = cur.Next
		cur.Next = head
		head = temp
	}

	return dummpy.Next
}

 

148. Sort List 链表排序

func sortList(head *ListNode) *ListNode {
	if head == nil || head.Next == nil {return head}
	var fast, slow, pre = head, head, head
	for fast != nil && fast.Next != nil {
		pre = slow
		slow = slow.Next
		fast = fast.Next.Next
	}
	pre.Next = nil
	return merge(sortList(head), sortList(slow))
}

func merge(l1 *ListNode, l2 *ListNode) *ListNode {
	if l1 == nil {return l2}
	if l2 == nil {return l1}
	if l1.Val < l2.Val {
		l1.Next = merge(l1.Next, l2)
		return l1
	} else {
		l2.Next = merge(l1, l2.Next)
		return l2
	}
}

 

206. Reverse Linked List 倒置链表

   非递归法

func reverseList(head *ListNode) *ListNode {
	var dummpy = &ListNode{Val: -1, Next: nil}
	for head != nil {
		var t = head.Next
		head.Next = dummpy.Next
		dummpy.Next = head
		head = t
	}
	return dummpy.Next
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值