链表操作----将单链表向右旋转 K 个位置

给定一个单链表,设计一个算法实现链表向右旋转 K 个位置。 

举例: 给定 1->2->3->4->5->6->NULL, K=3

             则     4->5->6->1->2->3->NULL


分析:

1. 这道题目的关键在于找到 尾节点和旋转后新链表的尾节点。 假设是 tail, new->tail.

然后只要进行 tail->next  = head;

                       head = new_tail->next;

                       new_tail->next = NULL;

2. 找两个尾节点可以采用 双指针的方法。

注意到 这两个节点 间距是 K,(初始化,tail = new_tail = head;) 

  STEP 1:tail 从 head 出发,先走 k 步

  STEP 2:  new_tail 和 tail 同时往前走, 当 tail 指向尾节点时, new_tail 的位置即所求。


struct ListNode{
  int val;
  ListNode *next;
  ListNode(int x)
    :val(x), next(NULL){}
};

int Length(ListNode *head)
{
  int len(0);
  for(; head; head = head->next, ++ len);
  return len;
}

ListNode* ReverseKList(ListNode *head, int k)
{
  int length = Length(head);
  if(length < 2 || k == 0 || k == length)
    return head;
  if(k < 0) return ReverseKList(head, k + length);
  if(k > length) return ReverseKList(head, k % length);

  assert(k > 0 && k < length);
  ListNode *tail(head), *new_tail(head);

  // tail 先走K步
  for(int i=0; i<k; ++i)
    tail = tail->next;

  // 一起走,知道 tail 指向尾节点
  while(tail->next){
    tail = tail->next;
    new_tail = new_tail->next;
  }

  // new_tail 指向旋转后的尾节点
  tail->next = head;
  head = new_tail->next;
  new_tail->next = NULL;

  return head;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值