Leetcode Rotating Five Steps


Here is a summary of the "problem of rotation" in Leetcode.
The first two "rotation" have the same meaning, the latter three have different meanings

  • Rotating linked list
  • Rotate the array
  • Rotate string
  • Rotate numbers
  • Rotate image

1. Rotating Linked List

Title description

Given a linked list, rotate the linked list and move each node of the linked list k positions to the right, where k is a non-negative number.

Example 1:

Input: 1->2->3->4->5->NULL, k = 2
Output: 4->5->1->2->3->NULL
Explanation:
Rotate to the right 1 step: 5- >1->2->3->4->NULL
rotate right 2 steps: 4->5->1->2->3->NULL
example 2:

Input: 0->1->2->NULL, k = 4
Output: 2->0->1->NULL
Explanation:
Rotate right 1 step: 2->0->1->NULL
Rotate right 2 Step: 1->2->0->NULL
Rotate right 3 steps: 0->1->2->NULL
Rotate right 4 steps: 2->0->1->NULL

Ideas

In fact, it is to take out the back section of the linked list and put it to the front.

As for which paragraph is behind, the kth node from the bottom starts and goes backwards. Here is a common problem with linked lists: the last problem

There are two ways to solve this problem. One is easy to think of. Isn't the kth from the bottom a positive number n-k+1 (n is the length of the linked list, counting from 1).
The second is the fast and slow pointer method in the linked list , which keeps two pointers at a distance of k. When the next pointer reaches the end, the previous pointer just points to the kth position from the bottom.

I will demonstrate the first easy one here. Why not do the second one? Because I’m lazy, my brain hurts, my brain hurts, my brain hurts when I see the code...

This problem needs to find the predecessor of the last kth node, and then it can be disconnected from the last kth node, and then spliced ​​to the head.

Java code

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode rotateRight(ListNode head, int k) {
        //特殊情况:链表为空或者长度为1
        if(head == null || head.next == null) return head;
        //计算链表长度
        int len = 1;
        ListNode p = head;
        while(p.next!=null){
            len++;
            p = p.next;
        }
        //此时p指向尾节点
        
        // 右移动k与右移k%len相同
        k = k%len;
        if(k == 0) return head;// 没有移动,直接返回
        
        // 原问题等价于找出倒数第k个节点,然后断开插入到头部
        // 倒数第k个等于正数第Len-k个(从0开始计数)
        
        // 而要想从第k个断开,就要找到它的的前驱,就是正数第Len-k-1个(从0开始计数)
        int cu = 0;
        ListNode q = head;
        while(cu!=len-k-1){
            cu++;
            q = q.next;
        }
        // 断开链表,并拼接
        ListNode lnew = q.next;
        q.next = null;
        p.next = head;
        return lnew;
        
    }
}

2. Rotate the array

Title description

Given an array, move the elements in the array k positions to the right, where k is a non-negative number.

Example 1:

Input: [1,2,3,4,5,6,7] and k = 3
Output: [5,6,7,1,2,3,4]
Explanation:
Rotate to the right 1 step: [7,1 ,2,3,4,5,6]
Rotate right 2 steps: [6,7,1,2,3,4,5]
Rotate right 3 steps: [5,6,7,1,2,3 ,4]
Example 2:

Input: [-1, -100,3,99] and k = 2
Output: [3,99, -1, -100]
Explanation:
rotation to the right Step 1: [99, -1, -100,3]
to Rotate right 2 steps: [3,99,-1,-100]
Description:

Think of as many solutions as possible. There are at least three different ways to solve this problem.
It is required to use an in-place algorithm with a space complexity of O(1).

Idea One

Unlike the rotating linked list, the array cannot be taken down half of the time and put to the front because the space complexity of the problem is O(1).
Therefore, the most direct way is to move one by one.
Each time the last element is recorded as temp, the elements before it are assigned to the next one one by one, and temp is assigned to nums[0] at the end.
Repeat this process k times, which means k rotations

Java code (1)

class Solution {
    public void rotate(int[] nums, int k) {
    //考虑特殊情况
        if(nums == null||nums.length == 0||nums.length == 1) return;
        int len = nums.length;
        if(k%len == 0) return;
        while(k>0){
            int temp = nums[len-1];//记录最后一个元素
            //从前向后移动一步
            for(int i = len-1;i>0;i--){
                nums[i] = nums[i-1];
            }
            //将第一个元素放到开头
            nums[0] = temp;
            k--;
        }
        
    }
}

Idea two

Reverse the whole first,
then reverse the first half, and reverse the
second half

Java code (2)

//从索引start 到end反转一个数组
  private void reverse(int[] nums, int start, int end) {
        while (start < end) {
            int temp = nums[start];
            nums[start] = nums[end];
            nums[end] = temp;
            start++;
            end--;
        }
    }

class Solution {
    public void rotate(int[] nums, int k) {
    //考虑特殊情况
        if(nums == null||nums.length == 0||nums.length == 1) return;
        int len = nums.length;
        if(k%len == 0) return;
        reverse(nums,0,len-1);
    	reverse(nums,0,k-1);
        reverse(nums,k,n-1);
    }
}

3. Rotate the string

Title description

Given two strings, A and B.

The rotation operation of A is to move the leftmost character of A to the rightmost. For example, if A ='abcde', the result will be'bcdea' after one move. If after several rotations, A can become B, then return True.

Example 1:
Input: A ='abcde', B ='cdeab'
Output: true

Example 2:
Input: A ='abcde', B ='abced'
Output: false
Note:

The length of A and B does not exceed 100.

Ideas

If A can become B through rotation, then the two successively spliced ​​A includes all the rotations of A, and must also include B.

Therefore, concatenate two A's, and return true if B is in the concatenated string of two A's; otherwise, return false

Java code

class Solution {
    public boolean rotateString(String A, String B) {
        //特殊情况
        if(A == null&&B==null) return true;
        else if(A == null &&B!=null) return false;
        else if(B == null && A!=null) return false;
        int lena = A.length();
        int lenb = B.length();
        if(lena!=lenb) return false;//长度要相等
        
        //拼接两个A
        StringBuilder sb = new StringBuilder();
        sb.append(A);
        sb.append(A);
        
        //如果B在两个A的连续拼接后的字符串中,则返回true,否则,返回false
        if(sb.toString().contains(B)) return true;
        else return false;
    }
}

4. Rotate the number

Title description

We call a number X a good number. If each of its digits is rotated 180 degrees one by one, we can still get a valid number that is different from X. Every digit is required to be rotated.

If each digit of a number is still a number after being rotated, the number is valid. 0, 1, and 8 are still themselves after being rotated; 2 and 5 can be rotated into each other; 6 and 9 are the same, except for these other numbers are no longer valid numbers after rotation.

Now we have a positive integer N. Calculate how many numbers X from 1 to N is a good number?

Example:
Input: 10
Output: 4
Explanation:
There are four good numbers in [1, 10]: 2, 5, 6, 9.
Note that 1 and 10 are not good numbers, because they do not change after rotation.

Ideas

The key is to understand the meaning of the question, what is a "good number"? That is , after each bit is rotated 180 degrees, it is still a number , and it is different from the original .
Since each digit is required, it is necessary to carry out the common " bit-by-digit stripping " of the numbers . This method is not difficult, and it is often used in the questions, so remember.

Then it is to judge "good numbers".

One digit is just these 10: 0 1 2 3 4 5 6 7 8 9 If it is
rotated by 180 degrees, it is still a number. There is 0 1 2 5 6 8 9 If it is
rotated by 180 degrees, it is still a number, but it is the same as the original number. If 0 1 8
meets the 180 degree rotation, it is still a number, and the difference from the original is only 2 5 6 9
and the remaining 3 4 7. Both conditions are not met.

Therefore, as long as a certain bit is 3 4 7, the number is definitely not a good number, and it returns false directly.
If 2 5 6 9 is encountered, it means that the bit satisfies two conditions and continues to judge other bits.
When encountering a certain digit of 0 1 8 these three numbers, it can neither indicate that the number is not a "good number" (other digits may satisfy the "good number condition"), nor that it is a "good number" (the digit is not Satisfy the "good number" condition), that is, do not change the judgment of the number, so there is no need to deal with them.

In fact, the default number is not a "good number", that is, flag=false, which is the treatment of this situation. If a certain digit of a number has 0 1 8 only the other digits are used to "save" the number, if the other digits meet the conditions, then change the flag to true, otherwise, it is false.

Java code

class Solution {
    public int rotatedDigits(int N) {
        int count = 0;
        //从1到N逐个判断
        for(int i = 1;i<=N;i++){
            if(isGoodNum(i)) count++;
        }
        return count;
    }
    //判断一个数字是否是“好数”
    public boolean isGoodNum(int x){
        boolean flag = false;
        while(x!=0){
            int t = x%10;
            if(t == 3|| t == 4 || t== 7) return false;
            else if(t == 2|| t==5||t==6||t == 9) flag = true;
            x = x/10;
        }
        if(flag) return true;
        else return false;
    }
}

5. Rotate the image

Title description

Given an n × n two-dimensional matrix represents an image.

Rotate the image 90 degrees clockwise.

Description:

You have to rotate the image in place, which means you need to directly modify the input two-dimensional matrix. Please do not use another matrix to rotate the image.

Example 1:

Given matrix =
[
[1,2,3],
[4,5,6],
[7,8,9]
],

Rotate the input matrix in place so that it becomes:
[
[7,4,1],
[8,5,2],
[9,6,3]
]
Example 2:

Given matrix =
[
[5, 1, 9,11],
[2, 4, 8,10],
[13, 3, 6, 7],
[15,14,12,16]
],

Rotate the input matrix in place so that it becomes:
[
[15,13, ​​2, 5],
[14, 3, 4, 1],
[12, 6, 8, 9],
[16, 7,10,11 ]
]

Idea One

Rotate 90 degrees clockwise: In fact, the two-dimensional array is first swapped up and down, and then swapped along the diagonal (\).

Java code (1)

class Solution {
    //交换二维数组两个点
    public void swap(int[][] matrix,int x1,int y1,int x2,int y2){
        int temp = matrix[x1][y1];
        matrix[x1][y1] = matrix[x2][y2];
        matrix[x2][y2] = temp;
    }
    
    public void rotate(int[][] matrix) {
        int len = matrix.length;
        //上下交换
        for(int i=0;i<len/2;i++){
            for(int j=0;j<len;j++){
                swap(matrix,i,j,len-i-1,j);
            }
        }
        //沿对角线交换
        for(int i=0;i<len;i++){
            for(int j=i;j<len;j++){
                swap(matrix,i,j,j,i);
            }
        }
    }
}

Idea two

Two layers of loops, move one by one, and exchange four points each time. This is hard to remember, and those indexes make me dizzy. Still the idea is simple and easy to understand.

Java code (2)

class Solution {
	public void rotate(int[][] matrix) {
	        int len = matrix.length;
	        for(int i=0;i<len/2;i++){
	            int start = i;
	            int end = len-i-1;
	            for(int j = 0;j<end-start;j++){
	                //交换
	                int temp = matrix[start][start+j];
	                matrix[start][start+j] = matrix[end-j][start];
	                matrix[end-j][start] = matrix[end][end-j];
	                matrix[end][end-j] = matrix[start+j][end];
	                matrix[start+j][end] = temp;
	            }
	    }
    }

Guess you like

Origin blog.csdn.net/fxjzzyo/article/details/87969971