# Sword finger offer java day30 divide and conquer algorithm

Posted by grimmier on Thu, 30 Sep 2021 21:58:43 +0200

## T1 17. Print from 1 to the maximum n digits

leetcode returns int [] without considering the large number. The original book considers the case that the large number is out of bounds

Large number out of bounds is not considered

```class Solution {
public int[] printNumbers(int n) {
int m = (int)Math.pow(10,n)-1; //Number of prints to be printed n times of 10 (starting from 1)
int[] res = new int[m];
for(int i=0;i<m;i++){
res[i] = i+1;
}

return res;
}
}
```

k divine solution Consider that the large number is out of bounds. Do not consider this question. It is required to return int []

1. Variable types representing large numbers:
Whether it is short / int / long... Any variable type, the value range of numbers is limited. Therefore, a large number indicates that the String type is applied
2. String set to generate numbers:
When using int type, each round can generate the next number by + 1 + 1, and this method cannot be applied to String type. In addition, the carry operation efficiency of String type numbers is low. For example, "9999" to "10000" need to be judged from one bit to thousands, and carry for 4 times.

It can be seen from the observation that the generated list is actually the full arrangement of nn bits 00 - 99. Therefore, the carry operation can be avoided and the String list of numbers can be generated recursively.

1. Generate full permutation recursively:
Based on the idea of divide and conquer algorithm, fix the high bit first and recurse to the low bit. When the single bit has been fixed, add the string of numbers. For example, when n = 2n=2 (number range 1 - 991 − 99), fix the ten bits as 00 - 99, turn on recursion in sequence, fix the bits 00 - 99, terminate recursion and add a number string.

Author: jyd
Source: LeetCode

At the same time, it is also necessary to deal with high-order redundant zeros, such as "001" and "099"

Judge that all bits are 9: n-start = nine

```class Solution {
StringBuilder res;
int nine = 0, count = 0, start, n;
char[] num, loop = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; //Number of digits looped up
public String printNumbers(int n) {
this.n = n;
res = new StringBuilder();
num = new char[n];//n represents the number of digits
start = n - 1; //Get the left border
dfs(0);
res.deleteCharAt(res.length() - 1); //Remove the last ','
return res.toString();
}

//Divide and conquer print array
void dfs(int x) {
if(x == n) { // Termination condition: all bits have been fixed
String s = String.valueOf(num).substring(start); //After the character array is converted to String, remove the high-order 0, and substring means to return from start
if(!s.equals("0")) res.append(s + ",");
if(n - start == nine) start--; //The left boundary of all 9 numbers is shifted one bit to the left
return;
}
for(char i : loop) {
if(i == '9') nine++;
num[x] = i;
dfs(x + 1);
}
nine--;
}
}

Author: jyd
Source: force buckle( LeetCode)
```

## T2 51. Reverse order pairs in the array

Merge sort

When left subarray current element > right subarray current element

Then "left subarray current element to end element" and "right subarray current element" form several reverse order trees

```class Solution {
int count; //global variable
public int reversePairs(int[] nums) {
this.count = 0;
marge(nums,0,nums.length-1); //Merge sort
return count;
}

//Inverse number function
public void marge(int[] nums,int left,int right){
int mid = left + ((right - left) >> 1); //Shift right faster than divide by 2

if(left < right){
marge(nums, left , mid);  //branch
marge(nums , mid+1 , right);
margeSort(nums , left , mid , right); //Sort sorted arrays
}
}

//Sorting after divide and conquer
public void margeSort(int[] nums,int left,int mid,int right){
int[] tmp = new int[right - left+1]; //Store the arranged array
int index = 0; //The index of the sorted completed array
int temp1=left , temp2=mid+1; // Left array start subscript, right array start subscript

while(temp1<=mid && temp2<=right){ // Any array is out of bounds
if(nums[temp1] <= nums[temp2]){ //Occurrence of inverse ordinal number
tmp[index++] = nums[temp1++]; //Assign first and then add 1
}else{
count += (mid-temp1+1); //Left subarray current element to end element
tmp[index++] = nums[temp2++]; //Assign first and then add 1
}
}

while(temp1<=mid){
tmp[index++] = nums[temp1++]; //Assign a value first, then add 1, and put the remaining left array into tmp
}

while(temp2<=right){
tmp[index++] = nums[temp2++]; //Assign a value first, then add 1, and put the remaining right array into tmp
}

//The sorted array covers the corresponding position of the original array
for(int i=0;i<tmp.length;i++)
nums[i+left] = tmp[i];
}
}
```

Topics: Java Algorithm leetcode