分类: 代码练习

  • LeetCode 109. 有序链表转换二叉搜索树

    class Solution {
        public TreeNode sortedListToBST(ListNode head) {
            return partition(head, getLength(head));
        }
    
        public int getLength(ListNode head) {
            int length = 0;
            while (head != null) {
                length++;
                head = head.next;
            }
            return length;
        }
    
        public TreeNode partition(ListNode head, int length) {
            if (length == 0) return null;
            if (length == 1) return new TreeNode(head.val);
            int mid = length / 2 - 1;
            ListNode node = head;
            for (int i = 0; i < mid; i++) {
                node = node.next;
            }
            ListNode now = node.next;
            node.next = null;
            TreeNode tree = new TreeNode(now.val);
            int newLen = mid + 1;
            tree.left = partition(head, newLen);
            tree.right = partition(now.next, length - newLen - 1);
            return tree;
        }
    }
  • 1494. 并行课程 II

    给你一个整数 n 表示某所大学里课程的数目,编号为 1 到 n ,数组 dependencies 中, dependencies[i] = [xi, yi]  表示一个先修课的关系,也就是课程 xi 必须在课程 yi 之前上。同时你还有一个整数 k 。

    在一个学期中,你 最多 可以同时上 k 门课,前提是这些课的先修课在之前的学期里已经上过了。

    请你返回上完所有课最少需要多少个学期。题目保证一定存在一种上完所有课的方式。

    输入:n = 4, dependencies = [[2,1],[3,1],[1,4]], k = 2
    输出:3 
    解释:上图展示了题目输入的图。在第一个学期中,我们可以上课程 2 和课程 3 。然后第二个学期上课程 1 ,第三个学期上课程 4 。
    

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/parallel-courses-ii
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    class Solution {
        int[] mask=new int[15];
        int[] dp=new int[1<<15];
        int[] cnt=new int[1<<15];
        //dp[state] 表示上完状态为state的课程需要多少学期 state第n位为1 则说明课程n已经上过了
       //state第n位为0 则说明课程n还没上过
        //mask[i]  表示课程i需要先修课程的掩码  mask[i]第j位为1说明 第j门课是i的先修课程 为0 则说明第j门课不是i的先修课程
        //cnt[state] 表示状态state中1的个数 也就是state下已完成课程的数目
        public int minNumberOfSemesters(int n, int[][] dependencies, int k) {
            int N=1<<n;
            for(int i=0;i<n;i++) mask[i]=0;
            //只需记录上一级的先修课程 先修课程的先修课程不需要记录
            //因为只有先修课程的先修课程上完 先修课程才能上
            for(int[] d:dependencies) mask[d[1]-1] |=1<<(d[0]-1);
            cnt[0]=0;
            for(int i=1;i<N;i++) cnt[i]=cnt[i>>1]+(i&1);
            for(int i=1;i<N;i++) dp[i]=16; //天数最多为15
            dp[0]=0;
            for(int i=0;i<N;i++)
            {
                if(dp[i]<=n) //上完所有课最多需要n学期 如果dp[i]>n 说明i状态无法达到
                {
                    //System.out.print(i+" ");
                  // i为所有课程的完成状态 j为课程序号  
                  //(i>>j& 0x1)==0 表示i的第j位不是1说明 该课程还没有上
                  //(mask[j] & i) == mask[j] 说明课程j的先修课程已经上完(i中对应mask[j]所有为1的bit也为1) 
                  //上述条件满足的情况下 将cur的第j位置1 说明该课程可以在当前学期完成
                  int cur=0;
                  for(int j=0;j<n;j++)
                  {
                      if( (i>>j& 0x1)==0 && (mask[j] & i) == mask[j] ) cur|=1<<j;
                  }
                  //l中包括了当前学期内所有可以完成的课程 其中的课程可以选择在本学期完成 也可以不在
                 // j-1 & l 表示逐步将l中的1从低位开始 每次迭代减少一个(课程)
                 //当前状态j中的课程数o[j]小于k 说明可以在本学期完成 因此将j中课程加入原始状态i( i|j )
                 //dp[i]+1 表示学习天数增加一天
                  for(int j=cur;j!=0;j=j-1&cur)
                  {
                    if(cnt[j]<=k) dp[i|j]=Math.min(dp[i|j],dp[i]+1);
                  }
                }
            }
            return dp[N-1];
        }
    }
    

  • 出栈排列

    一个优化过的求所有出栈排列的函数。

            public static void GetAllStackArrangement(int[] array, int index, int[] ans,  int ansIndex, int stackIndex)
            {
                if (index >= array.Length && stackIndex >= ans.Length)
                {
                    Console.WriteLine(string.Join(", ", ans));
                    return;
                }
                if(stackIndex >= ans.Length)
                {
                    int temp = ans[ans.Length - 1];
                    ans[ans.Length - 1] = array[index++];
                    GetAllStackArrangement(array, index, ans, ansIndex, ans.Length - 1);
                    ans[ans.Length - 1] = temp;
                }
                else if(index >= array.Length)
                {
                    int temp = ans[ansIndex], temp2 = ans[stackIndex];
                    ans[ansIndex++] = ans[stackIndex++];
                    GetAllStackArrangement(array, index, ans, ansIndex, stackIndex);
                    ans[ansIndex - 1] = temp;
                    ans[stackIndex - 1] = temp2;
                }
                else
                {
                    int temp = ans[ansIndex] , temp2 = ans[stackIndex];
                    ans[ansIndex++] = ans[stackIndex++];
                    GetAllStackArrangement(array, index, ans, ansIndex, stackIndex);
                    ansIndex--; stackIndex--;
                    ans[ansIndex] = temp; ans[stackIndex] = temp2;
                    temp = ans[--stackIndex];
                    ans[stackIndex] = array[index++];
                    GetAllStackArrangement(array, index, ans, ansIndex, stackIndex);
                    ans[stackIndex] = temp;
                }
            }
  • 排序算法学习

    package com.dominic;
    import edu.princeton.cs.algs4.StdRandom;
    public class Sort {
        private static boolean less(Comparable x, Comparable y)
        { return x.compareTo(y) < 0; }
        private static void exchange(Comparable[] a, int i, int j)
        {    Comparable t = a[i]; a[i] = a[j]; a[j] = t;}
        public static void show(Comparable[] a){
            for (Comparable comparable : a)
                System.out.print(comparable + " ");
            System.out.println();
        }
        public static boolean isSorted(Comparable[] a){
            for (int i = 1;i < a.length;i++)
                if(less(a[i],a[i-1]))
                    return false;
                return true;
        }
        public static void selection(Comparable[] a){
            int N = a.length;
            for (int i = 0; i < N; i++) {
                int min = i;
                for (int j = i + 1; j < N; j++)
                    if (less(a[j], a[min])) min = j;
                    exchange(a,i,min);
            }
        }
        public static void insertion(Comparable[] a){
            int N = a.length;
            for (int i=1;i<N;i++){
                for (int j = i;j>0&&less(a[j],a[j-1]);j++)
                    exchange(a,j,j-1);
            }
        }
        public static void shell(Comparable[] a){
            int N = a.length;
            int h = 1;
            while (h < N/3)
                h = 3*h+1;
            while (h >= 1){
                for (int i = h;i < N;i++){
                    for(int j = i;j>=h && less(a[j],a[j-h]);j-=h)
                        exchange(a,j,j-h);
                }
                h = h/3;
            }
        }
        public static void merge(Comparable[] a){
            Comparable[] aux = new Comparable[a.length];
            _merge_sort(a, aux,0, a.length-1);
        }
        private static void _merge_sort(Comparable[] a, Comparable[] aux, int lo, int hi){
            if (hi <= lo) return;
            int mid = lo + (hi - lo)/2;
            _merge_sort(a, aux, lo, mid);
            _merge_sort(a, aux, mid+1, hi);
            _merge(a, aux, lo, mid, hi);
        }
        private static void _merge(Comparable[] a, Comparable[] aux, int lo, int mid, int hi){
            int i = lo, j = mid + 1;
            if (hi + 1 - lo >= 0) System.arraycopy(a, lo, aux, lo, hi + 1 - lo);
            for (int k = lo; k <= hi; k++){
                if      (i>mid)               a[k]=aux[j++];
                else if (j>hi)                a[k]=aux[i++];
                else if (less(aux[j],aux[i])) a[k]=aux[j++];
                else                          a[k]=aux[i++];
            }
        }
        public static void quick(Comparable[] a){
            StdRandom.shuffle(a);
            _quick_sort(a, 0, a.length-1);
        }
        private static void _quick_sort(Comparable[] a, int lo, int hi){
            if (hi <= lo) return;
            int j = _partition(a, lo, hi);
            _quick_sort(a, lo, j-1);
            _quick_sort(a, j+1, hi);
        }
        private static int _partition(Comparable[] a, int lo, int hi){
            int i = lo, j = hi + 1;
            Comparable v = a[lo];
            while(true){
                while(less(a[++i],v)) if(i==hi) break;
                while(less(v,a[--j])) if(j==lo) break;
                if(i >= j) break;
                exchange(a, i, j);
            }
            exchange(a, lo, j);
            return j;
        }
        public static void quick3way(Comparable[] a){
            StdRandom.shuffle(a);
            _quick3way_sort(a, 0, a.length-1);
        }
        private static void _quick3way_sort(Comparable[] a, int lo, int hi){
            if (hi<=lo) return;
            int lt = lo, i = lo + 1, gt = hi;
            Comparable v = a[lo];
            while(i <= gt){
                int cmp = a[i].compareTo(v);
                if (cmp<0) exchange(a, lt++, i++);
                else if (cmp > 0) exchange(a, i, gt--);
                else i++;
            }
            _quick3way_sort(a, lo, lt-1);
            _quick3way_sort(a, gt+1, hi);
        }
    }
    
  • 第一棵完全二叉树与树的输入

    啊,仿照数据结构上的二叉树递归写法根本实现不了,最后发现原来是要传递指针的呀,该死!还要注意形参与实参的区别,用于统计的数应该以指针的形式直接访问内存修改数据,而不是用形参。

    无论如何,我实现了自己的第一棵完全二叉树及树的输入,嘻嘻嘻。下面放上代码(很烂)。

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #define status int
    typedef struct Tree{
        char data;
        struct Tree *lchild;
        struct Tree *rchild;
    }Tree,*tree;
    tree CreatBiTree(char * string,int *p,tree t){
        if(*p>=strlen(string)) return NULL;
        if(string[*p]==' ')  return NULL;
        else{
            t=(Tree*)malloc(sizeof(Tree));
            t->data=string[*p];
            (*p)++;
            t->lchild=CreatBiTree(string, p, t->lchild);
            (*p)++;
            t->rchild=CreatBiTree(string, p, t->rchild);
        }
        return t;
    }
    status printTree(tree t){
        if(t==NULL) {
            printf("null ");
            return 0;
        }
        printf("%c ",t->data);
        printTree(t->lchild);
        printTree(t->rchild);
        return 0;
    }
    int main() {
        tree root;
        int *p;
        p=(int*)malloc(sizeof(int));
        *p=0;
        char * test;
        test=(char*)malloc(100* sizeof(char));
        gets(test);
        root=CreatBiTree(test,p,root);
        printf("root:      %c \nfull tree: ",root->data);
        printTree(root);
        printf("\np's trace: %d",*p);
        return 0;
    }
  • 136. 只出现一次的数字

    1. 交换律:a ^ b ^ c <=> a ^ c ^ b
    2. 任何数于0异或为任何数 0 ^ n => n
    3. 相同的数异或为0: n ^ n => 0

    var a = [2,3,2,4,4]

    2 ^ 3 ^ 2 ^ 4 ^ 4等价于 2 ^ 2 ^ 4 ^ 4 ^ 3 => 0 ^ 0 ^3 => 3

    这个异或法我真的没想到,还是基础不扎实呀!

    int singleNumber(int* nums, int numsSize){
        int n=nums[0];
        for(int i=1;i<numsSize;i++)
           n=n^nums[i];
        return n;
    }
  • C语言printf输出的小玩法

    在输出时候加上 “\033[ ; m …… \033[0m ” 即可使得输出的字体和背景是有颜色的。下面是颜色的定义:

    字背景颜色范围:40 – 49

    40:黑

    41:深红

    42:绿

    43:黄色

    44:蓝色

    45:紫色

    46:深绿

    47:白色

    字颜色:30 – 39

    30:黑

    31:红

    32:绿

    33:黄

    34:蓝色

    35:紫色

    36:深绿

    37:白色

    下面看一下:ANSI控制码的说明

    \33[0m 关闭所有属性 

    \33[1m 设置高亮度 

    \33[4m 下划线 

    \33[5m 闪烁 

    \33[7m 反显 

    \33[8m 消隐 

    \33[30m — \33[37m 设置前景色 

    \33[40m — \33[47m 设置背景色 

    \33[nA 光标上移n行 

    \33[nB 光标下移n行 

    \33[nC 光标右移n行 

    \33[nD 光标左移n行 

    \33[y;xH设置光标位置 

    \33[2J 清屏 

    \33[K 清除从光标到行尾的内容 

    \33[s 保存光标位置 

    \33[u 恢复光标位置 

    \33[?25l 隐藏光标 

    \33[?25h 显示光标

  • 一个去除字符串空格的小函数

    void removeBlanks(char * string) {
        int len = (int) strlen(string), count = 0;
        for (int i = 0; i < len; i++) {
            if (string[i] == ' ') {
                count++;
                continue;
            }
            string[i - count] = string[i];
        }
        string[len-count]=0;
    }

    用了几种复杂的方法,最后才回归本质😅。

  • 实现了代码很烂的KMP算法

    先是看算法导论和数据结构

    后来又自己又上YouTube看视频

    就是这个视频,讲得很清晰

    然后附上代码做纪念:

    int KMP(char * string, char * pattern){
        int len=(int)strlen(pattern),
            l=(int)strlen(string),
            *next;
        next=(int*)malloc((len+1)*sizeof(int));
        for(int i=1,j=0;i<len;i++){
            if(pattern[i]==pattern[j]) {
                next[i]=j+1;
                j++;
                continue;
            }
            if(j==0) continue;
            i--;
            j=(next[j]==0)?0:(next[j]-1);
        }
        for(int i=0,j=0;i<l;i++){
            if(string[i]==pattern[j]){
                j++;
                if(j==len) return i+1-len;
                continue;
            }
            if(j==0) continue;
            i--;
            j=next[j-1];
        }
        return -1;
    }

    以后再改进吧!继续努力💪!