# LeetCode 725. Separate linked list / 326. 3 power / Sword finger Offer 62. The last remaining number in the circle (Joseph Ring problem)

Posted by jurdygeorge on Thu, 23 Sep 2021 15:01:05 +0200

One question per day on September 22, 2021

## Title Description

Given a linked list whose head node is root, write a function to separate the linked list into k consecutive parts.

The length of each part should be as equal as possible: the length difference between any two parts cannot exceed 1, that is, some parts may be null.

These k parts should be output in the order they appear in the linked list, and the length of the front part should be greater than or equal to the length of the back part.

Returns a list of linked lists that meet the above rules.

Example: 1 - > 2 - > 3 - > 4, k = 5 / / 5 result [, , , , null]

Example 1:

Input:
root = [1, 2, 3], k = 5
Output: [, , , [], []]
Explanation:
Each part of the input and output should be a linked list, not an array.
For example, the entered node root val= 1, root.next.val = 2, \root.next.next.val = 3, and root.next.next.next = null.
The first output is output.val = 1, output.next = null.
The last element output is null, which represents that the last part is an empty linked list.

Example 2:

Input:
root = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], k = 3
Output: [1, 2, 3, 4], [5, 6, 7], [8, 9, 10]]
Explanation:
The input is divided into several consecutive parts, and the length difference of each part is no more than 1. The length of the front part is greater than or equal to the length of the rear part.

Tips:

Length range of root: [0, 1000]
Size range of each node entered: [0, 999]
Value range of k: [1, 50]

Source: LeetCode

## thinking

It's not a simple simulation
The idea is very simple, but the code is still difficult to implement

```/**
* public class ListNode {
*     int val;
*     ListNode next;
*     ListNode() {}
*     ListNode(int val) { this.val = val; }
*     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode[] splitListToParts(ListNode head, int k) {
int l = 0;

while(node != null){
l++;
node = node.next;
}

int t = l / k;
int remain = l % k;

ListNode[] res = new ListNode[k];
int tt = t;

int idx = 0;
while(idx < k){
res[idx] = node;

while(tt-- > 0 && node != null){
node = node.next;
}

if(remain > 0){
node = node.next;
remain--;
}
tt = t;
idx++;
}
idx = 1;
while(idx < k && node != null){
if(node.next == res[idx]){
node.next = null;
node = res[idx];
idx++;
}
else
node = node.next;
}
return res;
}
}
```

I don't know how to write it separately after one traversal
Learn how to write once

```/**
* public class ListNode {
*     int val;
*     ListNode next;
*     ListNode() {}
*     ListNode(int val) { this.val = val; }
*     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode[] splitListToParts(ListNode head, int k) {
int l = 0;
while(node != null){
node = node.next;
l++;
}
int t = l / k;
int remain = l % k;
ListNode[] res = new ListNode[k];
int idx = 0;
while(idx < k && node != null){
res[idx] = node;
//Because you want to reach the previous node of the next starting node
int step = t + (remain-- > 0 ? 1 : 0);
while(step-- > 1){
node = node.next;
}

ListNode cur = node.next;
node.next = null;
node = cur;
idx++;
}
return res;
}
}
```

# 326. Power of 3

One question per day on September 23, 2021

## Title Description

Given an integer, write a function to determine whether it is a power of 3. If yes, return true; Otherwise, false is returned.

The integer n is to the power of 3, which needs to be satisfied: there is an integer x so that n == 3x

Example 1:

Input: n = 27
Output: true

Example 2:

Input: n = 0
Output: false

Example 3:

Input: n = 9
Output: true

Example 4:

Input: n = 45
Output: false

Tips:

-2^31 <= n <= 2^31 - 1

Can you complete the problem without using loops or recursion?

Source: LeetCode

## thinking

First of all, the most conventional idea is to divide by 3 all the time. If the remainder is not 0, it is not the power of 3; If there is one left, it is

```class Solution {
public boolean isPowerOfThree(int n) {
while(n != 0 && n % 3 == 0){
n /= 3;
}
return n == 1;
}
}
```

Then type the watch,

```class Solution {
static Set<Integer> set = new HashSet<>();
static{
int i = 1;
while(i <= Integer.MAX_VALUE / 3){
i *= 3;
}
}
public boolean isPowerOfThree(int n) {
return n > 0 && set.contains(n);
}
}
```

Then note that I just started to write a table like this, and then reported a memory overflow error. After thinking about it, i*3 must be out of range

```class Solution {
static Set<Integer> set = new HashSet<>();
static{
int i = 1;
//error code
while(i * 3 <= Integer.MAX_VALUE){
i *= 3;
}
}
public boolean isPowerOfThree(int n) {
return n > 0 && set.contains(n);
}
}
```

Because 3 is a prime number, the power and factor of 3 are also the power of 3, so here we directly take the power of the largest 3 in the Integer range, and then take the remainder of n

```public class Solution {
//Knowing the limit of n, we can now infer that the maximum value of n, that is, the power of 3, is 116261467.
//Since 3 is a prime number, the factor of the maximum value can only be a power of 3. Therefore, if the maximum value is divided by n and the remainder is 0, the power of 3 is obtained
public boolean isPowerOfThree(int n) {
return n > 0 && 1162261467 % n == 0;
}
}
```

Next, use the toString() method to convert n into a ternary number
Then judge whether the ternary number is 10000... In this form, judge with the regular expression, and forget the regular expression here, but it will disappear at a glance

```public class Solution {
public boolean isPowerOfThree(int n) {
//The first method is used to convert the number n to a base of 3 and return it in the form of string;
//The second method is used to check whether there is a specific string in the string,
//This regular expression is used to check whether the string starts with 1, followed by 0 or more zeros, and does not contain any other values\$
return Integer.toString(n, 3).matches("^10*\$");
}
}
```

The next method is also mathematics
Because n = 3^x, find X and judge whether x is an integer, that is, find the logarithm of log based on 3 bits and n
Then, because there are logarithms based on 10 in java, use the formula to convert it

```public class Solution {
//This method is pure mathematical calculation, that is, I = log3 (n); In Java, there is a logarithm with the lower value of 10, so the formula becomes:
//log10(n)/log10(3) to judge whether the result is an integer
public boolean isPowerOfThree(int n) {
return (Math.log10(n) / Math.log10(3)) % 1 == 0;
}
}

```

# Sword finger Offer 62. The last remaining number in the circle

## Title Description

The N numbers 0,1, ···, n-1 are arranged in a circle, starting from the number 0, and the m-th number is deleted from the circle each time (counting from the next number after deletion). Find the last number left in the circle.

For example, the five numbers 0, 1, 2, 3 and 4 form a circle. Starting from the number 0, delete the third number each time, then the first four deleted numbers are 2, 0, 4 and 1 in turn, so the last remaining number is 3.

Example 1:

Input: n = 5, m = 3
Output: 3

Example 2:

Input: n = 10, m = 17
Output: 2

Limitations:

1 <= n <= 10^5
1 <= m <= 10^6

Source: LeetCode

## thinking

I met some problems in the written examination today. Let's review it
First, very intuitive simulation, very slow:

```class Solution {
public int lastRemaining(int n, int m) {
List<Integer> list = new ArrayList<>(n);
for (int i = 0; i < n; i++) {
}
int idx = 0;
while (n > 1) {
idx = (idx + m - 1) % n;
list.remove(idx);
n--;
}
return list.get(0);
}
}
```

Suppose the answer to this question is f(n, m)
Then the first deleted position is M% N, and then the position m%n+1 becomes the initial position of the problem of f(n -1, m), that is, the zero position
After deleting one, the problem becomes f(n - 1, m), assuming that the solution of the problem is x
Then the answer to the question of f(n, m) should be to move x positions on the basis of M% n positions
Recursion can be written, dynamic programming saves space

```class Solution {
public int lastRemaining(int n, int m) {
int pre = 0;
for(int i = 2; i <= n; i++){
int f = (m + pre) % i;
pre = f;
}
return pre;
}
}
```

Topics: Java leetcode