Rotate List by K places I am trying to solve the question at

:https://leetcode.com/problems/rotate-list/

Question:


  Given a linked list, rotate the list to the right by k places, where k
  is non-negative.
  
  Example 1:
  
  
  Input:  1-&gt;2-&gt;3-&gt;4-&gt;5-&gt;NULL, k = 2     
  Output: 4-&gt;5-&gt;1-&gt;2-&gt;3-&gt;NULL
  
  
  Explanation:
  
  
  rotate 1 steps to the right: 5-&gt;1-&gt;2-&gt;3-&gt;4-&gt;NULL   
  rotate 2 steps to the right: 4-&gt;5-&gt;1-&gt;2-&gt;3-&gt;NULL
  


//public class ListNode
//{
//    public int val;
//    public ListNode next;
//    public ListNode(int x) { val = x; }
//}



//k = number of places
//head =Given Linked List

    public  ListNode RotateRight(ListNode head, int k) {
        if (k &gt; 0 &amp;&amp; head != null) {
            ListNode tail = head,
            RotatedList = null,
            kthnode = head,
            kthPrevNode = head;
            int listLength = 0;
            while (tail != null) {
                listLength += 1;
                tail = tail.next;
            }

            k = k % listLength;
            if (k == 0 || listLength == 0) {
                return head;
            }

            for (int i = 0; i &lt; listLength - k; i++) {

                kthPrevNode = kthnode;

                kthnode = kthnode.next;

            }

            RotatedList = kthnode;
            kthPrevNode.next = null;
            while (kthnode.next != null) {
                kthnode = kthnode.next;
            }

            kthnode.next = head;
            return RotatedList;

        }

        return head;
    }
}
}


I have passed all test cases but I am looking to improve code efficiency and time complexity,Kindly let me know if there are any bad practices as well
if (k &gt; 0 &amp;&amp; head != null) {
            ...
            return RotatedList;

        }

        return head;



would be clearer (and more consistent with the other special case) as

        if (k &lt;= 0 || head == null) {
            return head;
        }

        ...
        return RotatedList;


(although really if k &lt; 0 I think it should throw new ArgumentOutOfRangeException(nameof(k))).




            ListNode tail = head,
            RotatedList = null,
            kthnode = head,
            kthPrevNode = head;



Most of these don't need to be declared so early. Declaring variables as late as possible (and, more generally, in the narrowest scope possible) helps to reduce cognitive load when maintaining the code.




            int listLength = 0;
            while (tail != null) {
                listLength += 1;
                tail = tail.next;
            }



This would be worth factoring out as a separate method Length(ListNode head).




            k = k % listLength;
            if (k == 0 || listLength == 0) {
                return head;
            }



This is sort-of buggy. If listLength == 0 then k % listLength will throw an ArithmeticException. However, you can never reach here in that case, because listLength == 0 is equivalent to head == null, and that was already handled in the first special case. To remove confusion, delete || listLength == 0. If you want to validate that condition, insert System.Diagnostics.Debug.Assert(listLength &gt; 0); before the % line.




            for (int i = 0; i &lt; listLength - k; i++) {

                kthPrevNode = kthnode;

                kthnode = kthnode.next;

            }



It's not actually necessary to track two nodes here. The invariant is that kthPrevNode.next == kthnode, so it suffices to track kthPrevNode.

Also, the blank lines seem excessive to me.




            RotatedList = kthnode;



It's conventional in C# that local variable names start with a lower case letter, so to avoid confusion I would rename RotatedList to rotatedList (or perhaps rotatedHead).



There are only two things where I can see that the efficiency can be improved: one is eliminating kthnode in the loop, as commented above; the other would be to hang on to the last node when finding the length, so that you don't need to find it a second time in the last few lines. (That would imply changing the factored out method to return an (int, ListNode) tuple).

As for time complexity, it's already optimal: linear time. Good job!