zcy算法入门笔记001

笔记仅用于学习,如有错误欢迎指正,谢谢
  1. 位运算

public class Code01_PrintBinary  {
    public static void print(int num){
        //十进制=》二进制
        for (int i = 31; i >= 0; i--) {
            System.out.print((num & (1<<i)) == 0 ? "0" : "1");
        }
        System.out.println();
    }
    public static void main(String[] args) {
        print(1000);
        //1.整型最大值
        int a = Integer.MAX_VALUE;

        //2.转二进制发现最高位为0, 0-30位表示值(有符号数)
        print(a);   //01111111111111111111111111111111

        //3.正数符号位为0;负数符号位为1,值为其他位取反+1
        print(-1);  //-1 =》11111111111111111111111111111111

        //4.最小值:肯定为负数符号位为1; 其他各位取反+1产生进位(忽略符号位)
        // 得到10000000000000000000000000000000 即2的31次方
        a = Integer.MIN_VALUE;
        print(a);     //10000000000000000000000000000000

        //5.取反
        int b = 342982741;
        int c = ~b;
        print(b);
        print(c);

        //6.
        //最小绝对值比最大绝对值多1;
        //0是分在非负领域的,所以正数范围:0~2的31次方-1;
        //负数:-2的31次方~-1;
        System.out.println(Integer.MIN_VALUE);  //-2147483648
        System.out.println(Integer.MAX_VALUE);  //2147483647

        //7.
        int d = 312907132;
        int e = 710701431;
        print(d);
        print(e);
        System.out.println("--------------");
        print(d|e);
        print(d&e);
        print(d^e);
        System.out.println("--------------");

        //8.最小数
        int f = 1024;
        print(f);
        print(f >>> 1);
        f = Integer.MIN_VALUE;  //系统最小数带符号右移和不带符号右移
        print(f);
        print(f>>1);    //带符号右移:新出现的位用符号位来补
        print(f>>>1);   //不带符号右移:新出现的位用0来补

        //9.相反数
        int g = 5;
        int h = (~g+1);
        System.out.println(g);
        System.out.println(h);
        System.out.println(g+"二进制数:");
        print(g);   //00000000000000000000000000000101  //正数的原码、反码和补码相同
        System.out.println(h+"二进制数:");
        print(h);   //11111111111111111111111111111011 =》-5的补码
        System.out.println("------------------------");

        //10.问题:最小数取相反数是什么?
        g = Integer.MIN_VALUE;
        h = ~g + 1;
        //  结果还是它自己
        System.out.println(g);
        System.out.println(h);
        System.out.println(-g);     //都为-2147483648
        print(g);
        print(h);

    }
}
  1. 阶乘求和

public class Code02_SumOfFactorial {
    public static long factorialSum(int N){
        long f = 1;     //接收阶乘
        long sum = 0;   //接收阶乘求和
        for (int i = 1; i <= N; i++) {
            f *= i;
            sum+=f;
        }
        return sum;
    }
    public static void main(String[] args) {
        System.out.println(factorialSum(2));    //3
        System.out.println(factorialSum(3));    //9
        System.out.println(factorialSum(4));    //33

    }
}
  1. 选择、冒泡、插入排序

public class Code03_SelectionSort {
    public static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    public static int[] sortTest(){ //用于生成1~100随机生成数字
        int[] arr = new int[10];
        for (int i = 0; i < arr.length; i++) {
            int num = (int)(Math.random()*100+1);
            arr[i] = num;
        }
        return arr;
    }

    public static void selectSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        int N = arr.length;
        for (int i = 0; i < N; i++) {
            int minValue = i;   //每轮第一个暂设为最小
            for (int j = i + 1; j < N; j++) {
                minValue = (arr[minValue] > arr[j] ? j : minValue);
            }
            swap(arr, minValue, i); //每次拿到最小和本轮开头元素交换
        }
    }

    public static void bubbleSort(int[] arr){
        if(arr==null || arr.length<2){
            return;
        }
        int N = arr.length;
        for (int end = N-1; end >= 0; end--) {    //升序每轮确定一个最大值
            for (int second = 1; second <= end; second++) { //从第二个数开始
                if(arr[second]<arr[second-1]){  //前数比后数大则交换
                    swap(arr, second, second-1);
                }
            }
        }

    }


    //直接插入排序:交换型
    public static void insertSort1(int[] arr){
        if(arr == null || arr.length<2){
            return;
        }
        int N = arr.length;
        for (int end = 1; end < N; end++) {
            for (int pre = end-1; pre >= 0 && arr[pre]>arr[pre+1]; pre--) {
                swap(arr, pre, pre+1);      //前后交换
            }
        }
    }

    //直接插入排序:移动插入型
    public static void insertSort2(int[] arr){
        for (int i = 0; i < arr.length-1; i++) {
            //取出需要排序的数;idx为了定位最后插入位置;
            int idx = i+1;
            int tmp = arr[idx];
            while (idx>0 && arr[idx-1]>tmp){    //比前面有序列表的数小则idx下标左移
                arr[idx] = arr[idx-1];          //先往后移动腾出空间
                idx--;
            }
            arr[idx] = tmp;       //每轮需要排序数插入指定位置
        }

    }

    public static void main(String[] args) {
        int[] arr = sortTest(); //  随机生成10位数组
        System.out.println(Arrays.toString(arr));
        selectSort(arr);
        System.out.println(Arrays.toString(arr));
        System.out.println("--------------------");
        arr = sortTest();
        System.out.println(Arrays.toString(arr));
        bubbleSort(arr);
        System.out.println(Arrays.toString(arr));
        System.out.println("--------------------");
        arr = sortTest();
        System.out.println(Arrays.toString(arr));
        insertSort1(arr);
        System.out.println(Arrays.toString(arr));
        System.out.println("--------------------");
        arr = sortTest();
        System.out.println(Arrays.toString(arr));
        insertSort2(arr);
        System.out.println(Arrays.toString(arr));

    }
}
  1. 任意的x,x属于[0,1),[0,x)范围上出现概率由原来的x调整成x平方

public class Code04_RandToRand {
    public static void main(String[] args) {
        int testTimes = 10000000;
        int count = 0;
        for (int i = 0; i < testTimes; i++) {
            if(Math.random()<0.75){
                count++;
            }
        }
        System.out.println((double) count/testTimes);

        System.out.println("=========");
        int K = 9;
        // [0,K) -> [0,8]
        int[] counts = new int[9];
        for (int i = 0; i < testTimes; i++) {
            int ans = (int) (Math.random() * K); // [0,K-1]
            counts[ans]++;
        }
        for (int i = 0; i < K; i++) {
            System.out.println(i + "这个数,出现了 " + counts[i] + " 次");
        }
        System.out.println("=========");
        count = 0;
        double x = 0.17;
        for (int i = 0; i < testTimes; i++) {
            if (xToXPower2() < x) {
                count++;
            }
        }
        System.out.println((double) count / (double) testTimes);
//        System.out.println(Math.pow(x, 2));
        System.out.println((double) 1 - Math.pow((double) 1 - x, 2));

        System.out.println("==========");

    }

    // 返回[0,1)的一个小数
    // 任意的x,x属于[0,1),[0,x)范围上的数出现概率由原来的x调整成x平方
    public static double xToXPower2() {
        //max:两次必须都是[0, x]范围上
//        return Math.max(Math.random(), Math.random());
        //min: 两次都是(1-x)->(1-x)²
        return Math.min(Math.random(), Math.random());
    }


}
  1. 借助等概率函数拓展等概率范围:例如1~5->1~7

public class Code04_probability {

    public static int f1(){
        /*此函数只能用,不能修改:等概率返回[1,5]的数*/
        return (int)(Math.random()*5+1);
    }
    public static int f2(){
        /*随机机制:只能用f1; 等概率返回0和1*/
        int ans = 0;
        do{
            ans = f1();
        }while (ans == 3);  //得到3就重随
        return ans<3 ? 0 : 1;
    }
    public static int f3(){
        /*得到000~111做到等概率 即0~7等概率返回一个*/
        return (f2()<<2) + (f2()<<1) + (f2()<<0);
    }
    public static int f4(){
        //0~6等概率返回一个
        int ans = 0;
        do{
            ans = f3();
        }while (ans == 7);
        return ans;
    }
    public static int g(){  //1~7
        return f4()+1;
    }
    public static void main(String[] args) {
        //1.有一个函数f()可以等概率得到1~5范围上的数,不借助其他随机机制; 
        //如何使用f等概率得到1~7范围上的数?
        /*思路:f1[1,5]->f2[0,1]
        * (1)改造成0、1发生器(等概率返回0和1);
        * (2)让1、2返回0; 让4、5返回1; 得到3让f重随;
        * (3)三次独立调用f2()得到000~111做到等概率
        * (4)得到的0~7继续让7重做-》 得到0~6,再+1-》 得到1~7等概率
        * (5)如何推广?例如3-19等概率->17~56等概率。
        *    <1>3~19一共17个数,一半是8个数; 3~10(返回0)/11(重随)/12~19(返回1)
        *    <2>17~56即0~39 看看需要多少二进制位; 6个二进制位
        *    <3>六次独立调用f2()得到0~63,当随机到40~63时重做,最后得到0~39等概率
        *    <4>+17得到结果
        * */
        int count = 0;
        int[] counts = new int[8];
//        System.out.println(Arrays.toString(counts));  //默认全0
        long testTimes = 10000000;
        /*for (int i = 0; i < testTimes; i++) {
            if(f2()==0){
                count++;
            }
        }
        System.out.println((double) count/testTimes);*/
        System.out.println("-----------------------");
        //在此验证
        for (int i=0; i<testTimes; i++){
//            int num = f3(); //f3返回000~111 即0~7等概率
//            int num = f4(); //f4返回0~6等概率
            int num = g(); //g返回1~7等概率
            counts[num]++;
        }
        for (int i = 0; i < 8; i++) {
            System.out.println(i+"出现次数为"+counts[i]+"次");
        }


    }
}

  1. 不等概率01转换成等概率01

public class Code05_Probability {

    public static int x() {
        //只知道x会以固定概率返回0和1,但是x的内容看不到
        return Math.random() < 0.73 ? 0 : 1;
    }
    //等概率返回0和1
    public static int y(){
        int ans = 0;
        do{
            ans = x();
        }while (ans == x());    //00或11的情况重做
        return ans;
    }

    public static void main(String[] args) {
        /*2.题目:01不等概率随机到01等概率随机
         * 已有f函数:得到0的概率是p,得到1的概率是(1-p),即固定概率;
         * 要求写g函数等概率返回0和1。
         * 思路:
         * 随两次得到00或11重随,得到01返回0,得到10返回1; 概率都为p(1-p);
         * */
        
    }
}
  1. 对数器的使用

public class Code06_Comparator {
    //生成随机样本自己做比对
    public static int[] lenRandomValueRandom(int maxLen, int maxValue){
        //返回一个arr数组,arr的长度[0,maxLen-1],arr中的每个值[0,maxValue-1]
        int len = (int)(Math.random()*maxLen);
        int[] ans = new int[len];
        for (int i=0; i<len; i++){
            ans[i] = (int)(Math.random()*maxValue);
        }
        return ans;
    }
    public static int[] copyArray(int[] arr){
        int[] ans = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            ans[i] = arr[i];
        }
        return ans;
    }
    /*public static boolean equalValues(int[] arr1, int[] arr2){//arr1和arr2一定等长
        for (int i = 0; i < arr1.length; i++) {
            if(arr1[i]!=arr2[i]){
                return false;
            }
        }
        return true;
    }*/
    public static boolean isSorted(int[] arr){//arr1和arr2一定等长
        if(arr.length<2){   //没有数或一个数默认有数
            return true;
        }
        int max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if(max>arr[i]){ //不符合升序则排序失败
                return false;
            }
            max = Math.max(max, arr[i]);
        }
        return true;
    }
    public static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    public static void selectSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        int N = arr.length;
        for (int i = 0; i < N; i++) {
            int minValue = i;   //每轮第一个暂设为最小
            for (int j = i + 1; j < N; j++) {
                minValue = (arr[minValue] > arr[j] ? j : minValue);
            }
            swap(arr, minValue, i); //每次拿到最小和本轮开头元素交换
        }
    }
    public static void bubbleSort(int[] arr){
        if(arr==null || arr.length<2){
            return;
        }
        int N = arr.length;
        for (int end = N-1; end >= 0; end--) {    //升序每轮确定一个最大值
            for (int second = 1; second <= end; second++) { //从第二个数开始
                if(arr[second]<arr[second-1]){  //前数比后数大则交换
                    swap(arr, second, second-1);
                }
            }
        }
    }
    public static void insertSort1(int[] arr){
        if(arr == null || arr.length<2){
            return;
        }
        int N = arr.length;
        for (int end = 1; end < N; end++) {
            for (int pre = end-1; pre >= 0 && arr[pre]>arr[pre+1]; pre--) {
                swap(arr, pre, pre+1);      //前后交换
            }
        }
    }

    public static void main(String[] args) {
        int maxLen = 10;
        int maxValue = 1000;
        int testTime = 10000;
        for (int i = 0; i < testTime; i++) {
            int[] arr1 = lenRandomValueRandom(maxLen, maxValue);
            int[] tmp = copyArray(arr1);    //备份
            selectSort(arr1);
//            insertSort1(arr2);
            if (!isSorted(arr1)){
                for (int j =0; j<tmp.length; j++){
                    System.out.print(tmp[j]+" ");   //打印备份
                }
                System.out.println();
                System.out.println("选择排序错了");
                break;    //有一个出错就退出
            }
        }


    }
}
  1. 有序数组中找num

public class Code07_BSExit {

    public static boolean find(int[] arr, int num){//有序数组找num
        if(arr==null || arr.length==0){
            return false;
        }
        int L = 0;
        int R = arr.length-1;
        while (L <= R){
            int mid = (L+R)/2;
            if(arr[mid] == num){
                return true;
            } else if (arr[mid] < num) {
                L = mid + 1;
            }else {
                R = mid - 1;
            }
        }
        return false;
    }
    //准备一个对数器,暴力找num
    public static boolean test(int[] sortedArr, int num){
        for (int cur : sortedArr){
            if(cur==num){
                return true;
            }
        }
        return false;
    }

    public static int[] generateRandomArray(int maxSize, int maxValue){
        int[] arr = new int[(int)((maxSize+1)*Math.random())];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int) (Math.random()*(maxValue+1))-(int) (Math.random()*maxValue);
        }
        return arr;
    }
    public static void main(String[] args) {
        //有序数组中找指定数
        int testTime = 1000000;     //测试次数
        int maxSize = 10;
        int maxValue = 100;
        boolean succeed = true;
        for (int i = 0; i < testTime; i++) {
            int[] arr = generateRandomArray(maxSize, maxValue);
            Arrays.sort(arr);
            //生成一个随机数用于查找
            int value = (int) (Math.random()*(maxValue+1))-(int) (Math.random()*maxValue);
            if(test(arr, value)!=find(arr,value)){
                System.out.println("出错了");
                succeed = false;
                break;
            }
        }
        System.out.println(succeed?"Nice!":"No!");

    }
}

  1. 有序数组中找到>=num最左的位置

public class Code08_BSNearLeft {
    //arr有序的,找 >=num 最左下标
    public static int mostLeftNoLessNumIndex(int[] arr, int num) {
        if (arr == null || arr.length == 0) {
            return -1;
        }
        int L = 0;
        int R = arr.length - 1;
        int ans = -1;   //若返回-1表示数组中没有任何一个数>=num
        while (L <= R) {
            int mid = (L + R) / 2;
            if (arr[mid] >= num) {
                ans = mid;  //只有>=num时才设置ans
                R = mid - 1;
            } else {    //arr[mid] < num
                L = mid + 1;
            }
        }
        return ans;
    }

    public static int[] generateRandomArray(int maxSize, int maxValue){
        int[] arr = new int[(int)(Math.random()*(maxSize+1))];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
        }
        return arr;
    }
    public static int test(int[] sortedArr, int num){//对数器
        for (int i = 0; i < sortedArr.length; i++) {
            if(sortedArr[i]>=num){
                return i;
            }
        }
        return -1;
    }
    // for test
    public static void printArray(int[] arr) {
        if (arr == null) {
            return;
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        //有序数组中找到>=num最左的位置
        int testTime = 1000000;
        int maxSize = 10;
        int maxValue = 100;
        boolean succeed = true;
        for (int i = 0; i < testTime; i++) {
            int[] arr = generateRandomArray(maxSize, maxValue);
            Arrays.sort(arr);
            int value = (int) ((maxValue + 1) * Math.random()) - (int) (maxValue * Math.random());
            if(test(arr, value)!=mostLeftNoLessNumIndex(arr, value)){
                printArray(arr);
                System.out.println(value);
                System.out.println(test(arr, value));
                System.out.println(mostLeftNoLessNumIndex(arr, value));
                succeed = false;
                break;
            }
        }
        System.out.println(succeed?"Nice!":"No");
    }
}
  1. 局部最小值

public class Code09_BSAwesome {

    // 生成随机数组,且相邻数不相等
    public static int[] randomArray(int maxLen, int maxValue) {
        int len = (int) (Math.random() * maxLen);
        int[] arr = new int[len];
        if (len > 0) {
            arr[0] = (int) (Math.random() * maxValue);
            for (int i = 1; i < len; i++) {
                do {
                    arr[i] = (int) (Math.random() * maxValue);
                } while (arr[i] == arr[i - 1]);
            }
        }
        return arr;
    }

    // 也用于测试
    public static boolean check(int[] arr, int minIndex) {
        if (arr.length == 0) {
            return minIndex == -1;
        }
        int left = minIndex - 1;
        int right = minIndex + 1;
        // 如果left、right为一个有效位置,则判断是否比局部最小值大;
        boolean leftBigger = left >= 0 ? arr[left] > arr[minIndex] : true;
        boolean rightBigger = right < arr.length ? arr[right] > arr[minIndex] : true;
        return leftBigger && rightBigger;
    }

    public static void printArray(int[] arr) {
        for (int num : arr) {
            System.out.print(num + " ");
        }
        System.out.println();
    }


    //arr满足整体无序,且相邻的数一定不能相等
    public static int oneMinIndex(int[] arr) {
        if (arr == null || arr.length == 0) {
            return -1;
        }
        int N = arr.length;
        if (N == 1) {
            return 0;
        }
        if (arr[0] < arr[1]) {
            return 0;
        }
        if (arr[N - 1] < arr[N - 2]) {
            return N - 1;
        }
        //开始二分
        int L = 0;
        int R = N - 1;
        //L..R肯定有局部最小
        while (L < R-1) {       //L < R-1、R 这样至少会有三个数
            int mid = (L + R) / 2;
            if (arr[mid] < arr[mid - 1] && arr[mid] < arr[mid + 1]) { //mid是局部最小值
                return mid;
            } else {
                //1 左 > 我  我 > 右       --> 去右边找
                //2 左 < 我  我 < 右       --> 去左边找
                //3 左 < 我  我 > 右
                if (arr[mid] > arr[mid - 1]) {
                    R = mid - 1;
                } else {
                    L = mid + 1;
                }
            }
        }
        return arr[L] < arr[R] ? L : R;
    }

    public static void main(String[] args) {
        int maxLen = 10;
        int maxValue = 200;
        int testTime = 10000000;
        System.out.println("测试开始");
        for (int i = 0; i < testTime; i++) {
            int[] arr = randomArray(maxLen, maxValue);
            int ans = oneMinIndex(arr);
            if (!check(arr, ans)) { //判断ans是否是arr的局部最小值
                printArray(arr);
                System.out.println(ans);
                break;
            }
        }
        System.out.println("测试结束");


    }
}
  1. 哈希表和有序表的使用

public class Code10_HashMapTreeMap {
    public static class Node {
        public int value;

        public Node(int v) {
            value = v;
        }
    }

    // (K V)表
    public static void main(String[] args) {
        /*1.哈希表不管加了多少条记录,增删改查都是O(1)的时间
        * 2.不过这个常数时间比较大,远远比数组寻址的常数时间大得多
        * */
        HashMap<String, String> map = new HashMap<>();
        map.put("zuochengyun", "我是左程云");
        System.out.println(map.containsKey("zuochengyun"));
        System.out.println(map.containsKey("zuo"));
        System.out.println(map.get("zuochengyun"));

        map.put("zuochengyun", "他是左程云");
        System.out.println(map.get("zuochengyun"));

//        map.remove("zuochengyun");
//        System.out.println(map.containsKey("zuochengyun"));
//        System.out.println(map.get("zuochengyun"));


        String test1 = "zuochengyun";
        String test2 = "zuochengyun";
        System.out.println(map.containsKey(test1));
        System.out.println(map.containsKey(test2));

        HashMap<Integer, String> map2 = new HashMap<>();
        map2.put(1234567, "我是1234567");

        Integer a = 1234567;
        Integer b = 1234567;

        System.out.println(a == b);
        System.out.println(map2.containsKey(a));    //哈希表不管内存地址,值一样就存在
        System.out.println(map2.containsKey(b));

        Node node1 = new Node(1);
        Node node2 = new Node(1);
        HashMap<Node, String> map3 = new HashMap<>();
        map3.put(node1, "我进来了!");
        //非基本类型按引用传递
        System.out.println(map3.containsKey(node1));    //true
        System.out.println(map3.containsKey(node2));    //false

        System.out.println("===================");

        TreeMap<Integer, String> treeMap1 = new TreeMap<>();

        treeMap1.put(3, "我是3");
        treeMap1.put(0, "我是3");
        treeMap1.put(7, "我是3");
        treeMap1.put(2, "我是3");
        treeMap1.put(5, "我是3");
        treeMap1.put(9, "我是3");

        System.out.println(treeMap1.containsKey(7));
        System.out.println(treeMap1.containsKey(6));
        System.out.println(treeMap1.get(3));

        treeMap1.put(3, "他是3");
        System.out.println(treeMap1.get(3));

        treeMap1.remove(3);
        System.out.println(treeMap1.get(3));

        System.out.println(treeMap1.firstKey());
        System.out.println(treeMap1.lastKey());
        // <=5 离5最近的key告诉我
        System.out.println(treeMap1.floorKey(5));
        // <=6 离6最近的key告诉我
        System.out.println(treeMap1.floorKey(6));
        // >=5 离5最近的key告诉我
        System.out.println(treeMap1.ceilingKey(5));
        // >=6 离6最近的key告诉我
        System.out.println(treeMap1.ceilingKey(6));

//        Node node3 = new Node(3);
//        Node node4 = new Node(4);
//        TreeMap<Node, String> treeMap2 = new TreeMap<>();
//        treeMap2.put(node3, "我是node3");
//        treeMap2.put(node4, "我是node4");

    }

}
  1. 单链表、双链表的反转

public class Code11_ReverseList {
    public static class Node {
        public int value;
        public Node next;

        public Node(int data) {
            value = data;
        }
    }

    public static class DoubleNode {
        public int value;
        public DoubleNode last;
        public DoubleNode next;

        public DoubleNode(int data) {
            value = data;
        }
    }

    public static Node reverseLinkedList(Node head) {
        Node pre = null;
        Node next = null;
        while (head != null) {
            next = head.next;
            head.next = pre;
            pre = head;
            head = next;
        }
        return pre;
    }

    public static DoubleNode reverseDoubleList(DoubleNode head) {
        DoubleNode pre = null;
        DoubleNode next = null;
        while (head != null) {
            next = head.next;
            head.next = pre;
            head.last = next;
            pre = head;
            head = next;
        }
        return pre;
    }

    public static Node testReverseLinkedList(Node head) {
        if (head == null) {
            return null;
        }
        ArrayList<Node> list = new ArrayList<>();
        while (head != null) {
            list.add(head);
            head = head.next;
        }
        list.get(0).next = null;
        int N = list.size();
        for (int i = 1; i < N; i++) {
            list.get(i).next = list.get(i - 1);
        }
        return list.get(N - 1);
    }

    public static DoubleNode testReverseDoubleList(DoubleNode head) {
        if (head == null) {
            return null;
        }
        ArrayList<DoubleNode> list = new ArrayList<>();
        while (head != null) {
            list.add(head);
            head = head.next;
        }
        list.get(0).next = null;
        DoubleNode pre = list.get(0);
        int N = list.size();
        for (int i = 1; i < N; i++) {
            DoubleNode cur = list.get(i);
            cur.last = null;
            cur.next = pre;
            pre.last = cur;
            pre = cur;
        }
        return list.get(N - 1);
    }

    // for test
    public static Node generateRandomLinkedList(int len, int value) {
        int size = (int) (Math.random() * (len + 1));
        if (size == 0) {
            return null;
        }
        size--;
        Node head = new Node((int) (Math.random() * (value + 1)));
        Node pre = head;
        while (size != 0) {
            Node cur = new Node((int) (Math.random() * (value + 1)));
            pre.next = cur;
            pre = cur;
            size--;
        }
        return head;
    }

    // for test
    public static DoubleNode generateRandomDoubleList(int len, int value) {
        int size = (int) (Math.random() * (len + 1));
        if (size == 0) {
            return null;
        }
        size--;
        DoubleNode head = new DoubleNode((int) (Math.random() * (value + 1)));
        DoubleNode pre = head;
        while (size != 0) {
            DoubleNode cur = new DoubleNode((int) (Math.random() * (value + 1)));
            pre.next = cur;
            cur.last = pre;
            pre = cur;
            size--;
        }
        return head;
    }

    // for test
    public static List<Integer> getLinkedListOriginOrder(Node head) {
        List<Integer> ans = new ArrayList<>();
        while (head != null) {
            ans.add(head.value);
            head = head.next;
        }
        return ans;
    }

    // for test
    public static boolean checkLinkedListReverse(List<Integer> origin, Node head) {
        for (int i = origin.size() - 1; i >= 0; i--) {
            if (!origin.get(i).equals(head.value)) {
                return false;
            }
            head = head.next;
        }
        return true;
    }

    // for test
    public static List<Integer> getDoubleListOriginOrder(DoubleNode head) {
        List<Integer> ans = new ArrayList<>();
        while (head != null) {
            ans.add(head.value);
            head = head.next;
        }
        return ans;
    }

    // for test
    public static boolean checkDoubleListReverse(List<Integer> origin, DoubleNode head) {
        DoubleNode end = null;
        for (int i = origin.size() - 1; i >= 0; i--) {
            if (!origin.get(i).equals(head.value)) {
                return false;
            }
            end = head;
            head = head.next;
        }
        for (int i = 0; i < origin.size(); i++) {
            if (!origin.get(i).equals(end.value)) {
                return false;
            }
            end = end.last;
        }
        return true;
    }


    public static void f(Node head) {
        head = head.next;
    }

    // for test
    public static void main(String[] args) {
        int len = 50;
        int value = 100;
        int testTime = 100000;
        System.out.println("test begin!");
        for (int i = 0; i < testTime; i++) {
            Node node1 = generateRandomLinkedList(len, value);
            List<Integer> list1 = getLinkedListOriginOrder(node1);
            node1 = reverseLinkedList(node1);
            if (!checkLinkedListReverse(list1, node1)) {
                System.out.println("Oops1!");
            }

            Node node2 = generateRandomLinkedList(len, value);
            List<Integer> list2 = getLinkedListOriginOrder(node2);
            node2 = testReverseLinkedList(node2);
            if (!checkLinkedListReverse(list2, node2)) {
                System.out.println("Oops2!");
            }

            DoubleNode node3 = generateRandomDoubleList(len, value);
            List<Integer> list3 = getDoubleListOriginOrder(node3);
            node3 = reverseDoubleList(node3);
            if (!checkDoubleListReverse(list3, node3)) {
                System.out.println("Oops3!");
            }

            DoubleNode node4 = generateRandomDoubleList(len, value);
            List<Integer> list4 = getDoubleListOriginOrder(node4);
            node4 = reverseDoubleList(node4);
            if (!checkDoubleListReverse(list4, node4)) {
                System.out.println("Oops4!");
            }

        }
        System.out.println("test finish!");

    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值