1. 死锁的必要条件
互斥条件:一个资源每次只能被一个进程使用。 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。 循环等待
死锁预防
我们可以通过破坏死锁产生的4个必要条件来 预防死锁,由于资源互斥是资源使用的固有特性是无法改变的。
破坏“不可剥夺”条件:一个进程不能获得所需要的全部资源时便处于等待状态,等待期间他占有的资源将被隐式的释放重新加入到 系统的资源列表中,可以被其他的进程使用,而等待的进程只有重新获得自己原有的资源以及新申请的资源才可以重新启动,执行。
破坏”请求与保持条件“:第一种方法静态分配即每个进程在开始执行时就申请他所需要的全部资源。第二种是动态分配即每个进程在申请所需要的资源时他本身不占用系统资源。
破坏“循环等待”条件:采用资源有序分配其基本思想是将系统中的所有资源顺序编号,将紧缺的,稀少的采用较大的编号,在申请资源时必须按照编号的顺序进行,一个进程只有获得较小编号的进程才能申请较大编号的进程。
死锁避免
死锁避免的基本思想:系统对进程发出的每一个系统能够满足的资源申请进行动态检查,并根据检查结果决定是否分配资源,如果分配后系统可能发生死锁,则不予分配,否则予以分配,这是一种保证系统不进入死锁状态的动态策略。
如果操作系统能保证所有进程在有限时间内得到需要的全部资源,则系统处于安全状态否则系统是不安全的。银行家算法
2. 散列冲突处理方法
开放定址法 就是一旦发生了冲突,就去寻找下一个空的散列地址(线性探测、二次、随机);再散列函数法,不产生聚集;链地址法;公共溢出区法
3.count(列名)
返回列名指定列的记录数,在统计结果的时候,会忽略列值为NULL的记录(不包括空字符串和0),即列值为NULL的记录不统计在内,COUNT(*)会把所有记录计入
4.
5.冒泡,选择,快排,堆排序每排一次就能确定一个元素位置
6.矩阵最小路径
import java.util.*;
public class Main {
public static int minPathSum(int[][] matrix){
int n=matrix.length;
int m=matrix[0].length;
int[][]dp=new int[n+1][m+1];
dp[0][0]=matrix[0][0];
for(int i=1;i<n;i++)
dp[i][0]=matrix[i][0]+dp[i-1][0];
for(int j=1;j<m;j++)
dp[0][j]=matrix[0][j]+dp[0][j-1];
for(int i=1;i<n;i++){
for(int j=1;j<m;j++){
dp[i][j]=matrix[i][j]+(dp[i-1][j]>dp[i][j-1]?dp[i][j-1]:dp[i-1][j]);
}
}
return dp[n-1][m-1];
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n=in.nextInt();
int m=in.nextInt();
int[][] a=new int[n][m];
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
a[i][j]=in.nextInt();
}
}
int res=minPathSum(a);
System.out.println(res);
}
}
7.
8、消消乐
最长递增子序列
class Solution {
public int lengthOfLIS(int[] nums) {
if (nums.length == 0) {
return 0;
}
int[] dp = new int[nums.length];
dp[0] = 1;
int maxans = 1;
for (int i = 1; i < nums.length; i++) {
dp[i] = 1;
for (int j = 0; j < i; j++) {
if (nums[i] > nums[j]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
maxans = Math.max(maxans, dp[i]);
}
return maxans;
}
}
方法二:贪心 + 二分查找
思路与算法
考虑一个简单的贪心,如果我们要使上升子序列尽可能的长,则我们需要让序列上升得尽可能慢,因此我们希望每次在上升子序列最后加上的那个数尽可能的小。
基于上面的贪心思路,我们维护一个数组 d[i],表示长度为 ii 的最长上升子序列的末尾元素的最小值,用 len 记录目前最长上升子序列的长度,起始时 len 为 1,d[1] = nums[0]。
同时我们可以注意到 d[i] 是关于 i单调递增的,根据 d 数组的单调性,我们可以使用二分查找寻找下标 i,优化时间复杂度。
class Solution {
public int lengthOfLIS(int[] nums) {
int len = 1, n = nums.length;
if (n == 0) {
return 0;
}
int[] d = new int[n + 1];
d[len] = nums[0];
for (int i = 1; i < n; ++i) {
if (nums[i] > d[len]) {
d[++len] = nums[i];
} else {
int l = 1, r = len, pos = 0; // 如果找不到说明所有的数都比 nums[i] 大,此时要更新 d[1],所以这里将 pos 设为 0
while (l <= r) {
int mid = (l + r) >> 1;
if (d[mid] < nums[i]) {
pos = mid;
l = mid + 1;
} else {
r = mid - 1;
}
}
d[pos + 1] = nums[i];
}
}
return len;
}
}
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Scanner str = new Scanner(System.in);
while (in.hasNextLine()) {
int n = in.nextInt();
int [][] arr = new int [n][2];
for(int i =0;i<n;i++){
String s = str.nextLine();
arr[i][0] = Integer.parseInt(s.split(" ")[0].trim());
arr[i][1] = Integer.parseInt(s.split(" ")[1].trim()); }
Arrays.sort(arr, new Comparator<int[]>() {
@Override public int compare(int[] o1, int[] o2) {
return o1[0] == o2[0] ? o1[1] - o2[1] : o2[0] - o1[0]; } });
int [] height = new int[n]; for(int i =0;i<n;i++){ height[i] = arr[i][1]; }
System.out.println(handler(height)); } }
public static int handler(int []height){
int [] top = new int[height.length]; int piles =0;
for (int i = 0;i<height.length;i++){ int poker = height[i];
int left = 0,right =piles; while (left < right) {
int mid = (left + right) /2;
if(top[mid] > poker){ right = mid; }
else if(top[mid] < poker){
left = mid +1; }
else{ right = mid; }
}
if(left == piles)piles++;
top[left] = poker; }
return piles; } }
9、