Solution of Dutch flag problem: additional space complexity O, time complexity O(N)

Keywords: Java Algorithm data structure Back-end

Dutch National Flag Problem

        a. Given a sequence arr and a number num, put > num on the right of the array and < = num on the left of the array
        b. Given a sequence arr and a number num, put > num on the right of the array, < num on the left of the array, and equal in the middle of the array
        a. b requirements of the topic: additional space complexity O(1), time complexity O(N)  

Idea:

        Title a idea: corresponding leftRightPart() method

        When arr [k] < = num: suppose there is an area of < = with left   =  - 1 represents the initial area of < = Num), k points to the current value (k starts from 0). If arr [k] < = num, exchange the current value and the value of the next bit of the < = area, left + + (let < = this area move to the right of the array), and let K + +. The purpose of exchange is to bring small values into the < = area. All values in this area are < = num values after the above operations.

        When arr [k] >   Num: at this time, K + + is used directly until K goes out of bounds. The whole process can be completed. K crosses values larger than num. the values exchanged at K and left + 1 positions (< = next bit of the area) are the process of incorporating small values into the < = area.

        Topic b idea: corresponding leftMidRightPart() method

        When arr[k]<   Num: suppose there are two regions (left = -1 represents the initial region less than num, and right = arr.length represents the initial region greater than Num), and k points to the current value (k starts from 0), if arr[k]   <  Exchange the values of num, arr[k] and arr[left+1], and then left + +, K++

        When arr[k] >   Num: if arr[k]   >  Num, exchange the values of arr[k] and arr[arr.length-1], and then right -- the processing of right is to include the value at the position just adjusted into    > In the area of num.    Here, arr[arr.length-1]     yes  > The value of the previous bit in the num area is exchanged, and the subsequent value is changed to the K position. At this time, the value of the K position is uncertain about its relationship with num, so let the circular index   i -= 1. The purpose of this step is to call back a loop that has been executed, so that the replaced value at k position can enter the judgment logic again.

        When arr[k]=   num: skip directly, and then K++

        When k == right, return and the processing is completed.

Summary: in fact, b thinking is like putting a string of chess pieces with an array on a table. Given a rule: determine a number, I will take the chess pieces greater than this number, you will take the chess pieces less than this number, and no one who is equal to this number will move. You and I represent the < num region and the > num region respectively. On the outside of these two regions are the numbers to be processed. The pending region is initially the whole array. Idea a is the simplification of idea b

package com.kali.quick;

import java.util.Arrays;

/**
 * Dutch National Flag Problem
 *      1.Given a sequence arr and a number num, put > num to the right of the array
 *      Put < = num on the left of the array
 *      2.Given a sequence arr and a number num, put > num to the right of the array
 *      Put < num on the left of the array and equal in the middle of the array
 *      1,2 Requirements: additional space complexity O(1), time complexity O(N)
 */
public class NetherlandsFlagIssue {
    public static void main(String[] args) {
        int[] arr = {1,3,4,2,7,5,11,2,6,9,8,15,7,7,9,7,7,6,4};
        /*int[] process = process(arr, 3);
        System.out.println(Arrays.toString(process));*/
        /*int[] ints = leftRightPart(arr, 4);
        System.out.println(Arrays.toString(ints));*/
        int[] tar = leftMidRightPart(arr, 7);
        System.out.println(Arrays.toString(tar));
    }

    //< = num on the left, > num on the right
    public static int[] leftRightPart(int[] arr,int num){
        int left = -1;
        int k = 0;
        for (int value : arr) {
            if (value <= num) {
                swap(arr, k, left + 1);
                left++;
            }
            k++;
        }
        return arr;
    }

    //The real Dutch flag problem < num on the left, > num on the right = num in the middle
    public static int[] leftMidRightPart(int[] arr,int num){
        int left = -1;
        int right = arr.length;
        int k = 0;
        for (int i = 0; i < arr.length; i++) {
            if(k == right){
                break;
            }
            if (arr[i] < num) {
                swap(arr, k, left+1);
                left++;
                k ++;
            }else if(arr[i] > num){
                swap(arr,k,right-1);
                i -= 1;
                right --;
            }else{
                k ++;
            }
        }
        return arr;
    }

    public static void swap(int[] arr,int m,int n){
        int temp = arr[m];
        arr[m] = arr[n];
        arr[n] = temp;
    }

    //Written according to your own ideas, only < = num is on the left and > num is on the right, which may not meet the complexity requirements
    public static int[] process(int[] arr,int wall){
        int[] des = new int[arr.length];
        int L = 0;
        for (int item : arr) {
            if (item <= wall) {
                des[L] = item;
                L++;
            }
        }

        for (int value : arr) {
            if (value > wall) {
                des[L++] = value;
            }
        }
        return des;
    }
}

Posted by Paddy on Thu, 11 Nov 2021 00:30:36 -0800