zoukankan      html  css  js  c++  java
  • LeetCode 25. K 个一组翻转链表

    我的LeetCode:https://leetcode-cn.com/u/ituring/

    我的LeetCode刷题源码[GitHub]:https://github.com/izhoujie/Algorithmcii

    LeetCode 25. K 个一组翻转链表

    题目

    给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。

    k 是一个正整数,它的值小于或等于链表的长度。

    如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

    示例:

    给你这个链表:1->2->3->4->5
    
    当 k = 2 时,应当返回: 2->1->4->3->5
    
    当 k = 3 时,应当返回: 3->2->1->4->5
    

    说明:

    • 你的算法只能使用常数的额外空间。
    • 你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/reverse-nodes-in-k-group
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    解题思路

    思路1-先分为k段,每段翻转后拼接回去

    先对原节点每k个节点分割,每个子段进行翻转,然后再处理拼接回去;

    算法复杂度:

    • 时间复杂度: $ {color{Magenta}{Omicronleft(n ight)}} $
    • 空间复杂度: $ {color{Magenta}{Omicronleft(k ight)}} $

    思路2-直接递归处理分段及分段翻转

    每k个段记录并递归,从最后k个段向上递归翻转拼接,节点处理比较绕;

    算法复杂度:

    • 时间复杂度: $ {color{Magenta}{Omicronleft(n ight)}} $
    • 空间复杂度: $ {color{Magenta}{Omicronleft(n ight)}} $

    算法源码示例

    package leetcode;
    
    /**
     * @author ZhouJie
     * @date 2020年1月13日 下午10:25:53 
     * @Description: 25. K 个一组翻转链表
     *
     */
    public class LeetCode_0025 {
    
    }
    
    // Definition for singly-linked list.
    class ListNode_0025 {
    	int val;
    	ListNode_0025 next;
    
    	ListNode_0025(int x) {
    		val = x;
    	}
    }
    
    class Solution_0025 {
    	/**
    	 * @author: ZhouJie
    	 * @date: 2020年2月4日 下午3:15:23 
    	 * @param: @param head
    	 * @param: @param k
    	 * @param: @return
    	 * @return: ListNode_0025
    	 * @Description: 1-迭代;
    	 *
    	 */
    	public ListNode_0025 reverseKGroup(ListNode_0025 head, int k) {
    		ListNode_0025 p1, p2, p3, newHead;
    		p1 = p2 = p3 = newHead = null;
    		int n = 1;
    		ListNode_0025 dummy = new ListNode_0025(0);
    		dummy.next = head;
    		while (head != null) {
    			dummy.next = head;
    			while (head != null && n < k) {
    				head = head.next;
    				n++;
    			}
    			if (n < k || head == null) {
    				break;
    			}
    			p2 = head;
    			p3 = head.next;
    			head.next = null;
    			// 翻转一段链表
    			reverse(null, dummy.next);
    			if (newHead == null) {
    				newHead = p2;
    			} else {
    				p1.next = p2;
    			}
    			p1 = dummy.next;
    			p1.next = p3;
    			head = p3;
    			n = 1;
    		}
    		return newHead == null ? dummy.next : newHead;
    	}
    
    	/**
    	 * @author: ZhouJie
    	 * @date: 2020年2月4日 下午3:20:04 
    	 * @param: @param tail
    	 * @param: @param head
    	 * @param: @return
    	 * @return: ListNode_0025
    	 * @Description: 翻转链表
    	 *
    	 */
    	private ListNode_0025 reverse(ListNode_0025 tail, ListNode_0025 head) {
    		if (head == null) {
    			return tail;
    		}
    		ListNode_0025 next = head.next;
    		head.next = tail;
    		return reverse(head, next);
    	}
    
    	/**
    	 * @author: ZhouJie
    	 * @date: 2020年2月4日 下午3:26:30 
    	 * @param: @param head
    	 * @param: @param k
    	 * @param: @return
    	 * @return: ListNode_0025
    	 * @Description: 2-递归;
    	 *
    	 */
    	public ListNode_0025 reverseKGroup_2(ListNode_0025 head, int k) {
    		ListNode_0025 now = head;
    		int count = 0;
    		while (now != null && count < k) {
    			now = now.next;
    			count++;
    		}
    		if (count == k) {
    			now = reverseKGroup_2(now, k);
    			// head是满足连续k个的最后一段首节点,now是最后一段尾节点的下一个节点
    			while (count-- > 0) {
    				ListNode_0025 temp = head.next;
    				head.next = now;
    				now = head;
    				head = temp;
    			}
    			// 返回当前段处理完后的头结点
    			return now;
    		}
    		return head;
    	}
    }
    
    
  • 相关阅读:
    五十四:CSS3之背景与渐变之渐变
    五十三:CSS3之背景与渐变之背景
    五十二:CSS3之圆角、边框、边界图片
    五十一:CSS3之基本选择器之伪元素
    五十:CSS3之基本选择器之CSS权重
    四十九:CSS3之基本选择器之伪类选择器之结构类之nth选择器
    四十八:CSS3之基本选择器之伪类选择器之UI元素状态伪类
    四十七:CSS3之基本选择器之伪类选择器之动态伪类
    四十六:CSS3之基本选择器新增加的属性选择器
    四十五:CSS3之基本选择器新增加的4种选择器
  • 原文地址:https://www.cnblogs.com/izhoujie/p/12902574.html
Copyright © 2011-2022 走看看