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;
}
}
分类: 代码练习
-
LeetCode 109. 有序链表转换二叉搜索树
-
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. 只出现一次的数字
- 交换律:a ^ b ^ c <=> a ^ c ^ b
- 任何数于0异或为任何数 0 ^ n => n
- 相同的数异或为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; }
以后再改进吧!继续努力💪!