计算机基础
CPU的时钟
Cpu的时钟就是CPU在处理数据是微观上是有先后顺序的,主观上看似是同步进行的,通常会使用脉冲图去表示。
计算cpu的效率,如CPU(N核 2.40G Hz):
N2.401024^3
字节?
**字节(byte)**是计算机的数据存储的基本单元,1个字节(byte)分为8个二进制位(bit)。一个英文字母(不分大小写)占一个字节的空间,一个中文汉字占两个字节的空间。英文标点占一个字节,中文标点占两个字节。
…… | 2^6 | 2^5 | 2^4 | 2^3 | 2^2 | 2^1 | 2^0 |
---|---|---|---|---|---|---|---|
…… | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
二进制如何转换为十进制:
1010 1010 —— 2^7+2^5+2^4+2^2+2^1
十进制如何转换为二进制:
根据数字的大小去比较(仅限数值较小)
Eg: 88
88>64 88-64=24 2^6 记1
24>16&&24<32 24-16=8 2^4 记1
8=8 2^3 记1
“够减记1,不够减记0”
0011 1000
1字节(Byte)=8位(bit)
1KB( Kilobyte,千字节)=1024B
1MB( Megabyte,兆字节)=1024KB
1GB( Gigabyte,吉字节,千兆)=1024MB
1TB( Trillionbyte,万亿字节,太字节)=1024GB
硬盘
电脑硬盘是计算机最主要的存储设备。CPU处理完成的数据,需要长时间保存,那么就需要硬盘的参与。固态硬盘损坏后不可修复,移动硬盘可修复。
[Fast ATA](百度百科-验证 ATA/10854244?fromModule=lemma_inlink)接口硬盘的最大外部传输率为16.6MB/s,而Ultra ATA接口的硬盘则达到33.3MB/s。
在计算机和软件领域也是不可兼得的,如效率快安全性就低,安全性高效率就低等。
硬盘的工作是长期保存数据。
内存
介于CPU和硬盘直接的存储数据的东西叫内存。
CPU产生的内容首先交给速度能跟上的CPU的内存,然后cpu剩下的90%的时间就可以先去处理其他事情,这个时候内存帮助cpu将内容转移到对应设备上。
操作系统
操作系统是人与计算机之间的接口,也是计算机的灵魂。操作系统有[ Microsoft Windows](百度百科-验证 Windows/3304184?fromModule=lemma_inlink),macOS,Linux等。
App直接和操作系统将数据通过驱动传递给了硬件。操作系统的南向接口是不一样的北向接口是一致的,因此在windows操作系统下开发的应用不能在linxu上应用,因为接口不一致。
Java
JVM
JRE(Java Runtime Environment)是java程序运行时的环境,包含jvm和核心类库;
JDK(Java Development Kit)是java程序开发工具包。(javac.exe和java.exe)
package 是说明,这个类型所在的包(文件夹)其位置,必须是java文件的第一个有效行。
//单行注释
/*
* 多行注释
* */
/**
* 文档注释
*/
Main 是类名,遵循大驼峰命名法
大驼峰命名法: 是指首字母大写,每个单词的首字母大写
类名属于标识符,遵循标识符声明规则,即:
1.不能数字开头
2.不能使用关键字
3.不能出现除了$和_以外的特殊字符
4.不能纯数字
养成习惯 先打全对括号 然后改光标位置;
方法需进行缩进:ctrl+f;
java基础数据类型
基础数据类型:包括4类8种;
整型数据、浮点型数据、字符型数据、布尔型数据
整型数据:byte(8位),short(16位),int(32位),long(64位);
*局部变量的声明:
* 分成,声明和赋值两个部分
* 声明格式: 类型 标识符;
*赋值:标识符=字面量;
*简化写法, 会将声明和赋值写在同一行 如:类型 标识符=字面量;
*
*注意!!!! 局部变量不赋值不可使用,否则会出错;
* */
long num=98765432l;
Long型要在最后加一个l;
btye的最大值,应该是二进制的0111 1111
最大值2^n-1,最小值-2^n (n是位数)
byte numb=0;
short nums=111;
int i=798765432;
long num=98765432l;
//btye的最大值,应该是二进制的0111 1111
//最大值2^n-1,最小值-2^n (n是位数)
浮点型 //456.789=45.678910=4.56789100 //浮点型有两种小类,分别为 float和double //其中,float叫单精度浮点数,double叫做双精度浮点数 //主要区别就是在字节长度上,float4个字节,double8个字节 //浮点数 用float来举例 //1.第一位,是符号位,1表示负数 //2.接下来8位叫做指数位,表示小数点偏移多少 //3.接下来32位,叫做尾数位,表示实际存储内容是什么
float n=4.45f;
double m=4.56;
字符型 占用两个字节(基础数据类型 必须有一个字符)
char c='w';
String str="ywy";//引用数据类型
布尔型
boolean flag=true;
运算符和表达式
表达式就是通过字面量,标识符,运算符的组合通过计算机得到一个固定结果的式子叫表达式。
标识符通常就是我们说的变量,也有可能是后续说的方法。
int a=1;
int b=5;
运算符
1.算数运算符:+ - * / % ++ -- += -= *=
2.位运算符:>> << >>> & | ^ ~
int i=89;
System.out.println(i>>1);
3.关系运算符: > < >= <= != ==(关系运算符 运算结束后得到一个Boolean类型的值)
int a1=4;
int b2=5;
System.out.println(a1>=b2);
4.逻辑运算符:& | ! && ||
System.out.println(a>=b);
//短路:&& ||
System.out.println(a<b||(a=a+8)<b);
System.out.println(a);
//不短路:& |
System.out.println(a<b|(a=a+8)<b);
System.out.println(a);
//目数(参与运算的元素)越多优先级越低
int a3=4;
int b3=5;
//三目运算符 判断大小
System.out.println("---------------------");
System.out.println(a3>b3?a3:b3);
基础类型之间的关系.
整形和字符之间可以相互转化的,但一定要注意一点 数据的字节容量,字符型两个字节,如果给字符型数据赋值时 超过两个字节,可能会引起问题 同样的,如果给整数型,赋值一个字符型数据的时候,也要注意大小限制。
//转化为3进制
int a=45;
System.out.println(Integer.toString(a, 3));
//
int a1=128;
byte xy=(byte)a1;
System.out.println(xy);
流程控制
流程控制有两种:一种叫循环,一种叫分支
if分支 格式:if(boolean表达式){代码块} 如果boolean表达式的结果为真,则去执行代码块 和if配套使用的是else 格式在if代码块后面,其含义是如果if不成立则运行else代码块
int a=3;
int b=6;
if(a>b) {
System.out.println("a大于b");
}else if(a==b){
System.out.println("a等于b");
}else {
System.out.println("a小于b");
}
if分支实例:
int a1=-1;
if(a1>=0&&a1<=100) {
if(a1>=90) {
System.out.println("优秀");
}else if(a1>=60&a1<90) {
System.out.println("良好");
}else{
System.out.println("不及格");
}
}else {
System.out.println("数据有误");
}
switch分支 /*格式:
- switch(目标标识符){
- case 路标:
- .......
- default:
- }
- */ 注意!!! long型不能放到Switch里面
switch分支实例:
int a3=5;
switch(a){
case 1:
System.out.println("内容是1");
break;
case 2:
System.out.println("内容是2");
break;
case 3:
System.out.println("内容是3");
break;
case 4:
System.out.println("内容是4");
break;
default:
System.out.println("数据有误");
break;
}
//z这是这年的第几天
int days=2;
int m=13;
switch(m) {
case 1:
days += 31;
case 2:
days += 28;
case 3:
days += 31;
case 4:
days += 30;
case 5:
days += 30;
case 6:
days += 31;
case 7:
days += 31;
case 8:
days += 31;
case 9:
days += 30;
case 10:
days += 31;
case 11:
days += 30;
case 12:
days += 31;
System.out.println(days);
break;
default:
System.out.println("有误");
break;
}
循环
for循环格式: /*
- for(表达式1;表达式2;表达式3){
- 代码块 ;
- }
- */
//0-100所有奇数的和
int a=0;
for(int i=0;i<=100;i++){
if(i%2 == 0) {
continue;
}
a+=i;
}
System.out.println(a);
//100-999之间的水仙花数
System.out.println("----------------");
int x=0;
int y=0;
int z=0;
int sum=0;
for(int i=100;i<1000;i++) {
x = i / 100;
y = i / 10 % 10;
z = i % 10;
sum = x*x*x+y*y*y+z*z*z;
if(sum==i) {
System.out.println(i);
}
}
/*while循环格式;
- while(boolean表达式){
- 代码块;
- }
- */
int sum1=0;
int j=1;
while(j<=100) {
sum1+=j;
j++;
}
System.out.println(sum1);
1.if适用于连续数据的分支 2.switch适用于离散数据的分支 3.for适用于一直循环次数的循环 4.while适用于已知退出条件的循环
例题
输出:
0 0 0 0
0 0 0
0 0
0
public static void main(String[] args) {
int n=5;
for(int i=0;i<=n;i++) {
for(int j=0;j<=n-i;j++) {
System.out.print("* ");
}
System.out.println();
}
}
//倒三角
public static void main(String[] args) {
int num=5;
int maxStar=2*num-1;
for(int i=0;i<num;i++) {
for(int j=0;j<i;j++) {
System.out.print(" ");
}
for(int j=0;j<maxStar-2*i;j++) {
System.out.print("* ");
}
System.out.println();
}
}
public static void main(String[] args) {
int num=5;
for(int i=0;i<num;i++) {
for(int j=0;j<num-1-i;j++) {
System.out.print(" ");
}
for(int j=0;j<i+1;j++) {
System.out.print("* ");
}
System.out.println();
}
}
9*9乘法表
public static void main(String[] args) {
int i,j;
for(i=9;i>=1;i--)
{
for(j=1;j<=i;j++)
{
System.out.print(j+"*"+i+"=");
System.out.printf("%-4d",i*j);
}
System.out.println();
}
}
鸡兔同笼
public static void main(String[] args) {
int head=17;
int foot=58;
for(int i=0;i<=head;i++) {
if(i*4+(head-i)*2==foot) {
System.out.println("有"+i+"个兔子"+(head-i)+"只鸡");
break;
}
}
}
数组
数组就是存放相同类型元素的容器,里面可以存放任何类型的数据但是要提前约定好放什么类型的数据
声明过程要遵循变量的声明规则 类型 标识符;
int[] arr= {1,2,3,4,5,6,7,8,9,0};//静态赋值
int[] arr1=new int[8]; //动态赋值
java内存分为三块:
-
程序计数器:记录你的java字节码运行到了哪一行;
-
本地方法栈:java里面有一种方法叫做native方法,这个本地方方法栈存的就是native方法运行的过程
-
虚拟机栈:这个里面存储的是Java的方法运行的过程
-
堆
-
方法区
数组的特点:
- 数组在内存中是连续的;
- 数组存放的内容类型是一致的;
- 数组在创建的时候,必须给出大小;
- 数组的大小穿件后不可改变;
数组是一个容器 对容器的操作有一个定义,定位,求长,替换
容器求长
System.out.println(arr.length);
定位:定位分两种,一种是知道定位,获得这个位置的值,还有一种是知道值,想知道这个值在第几个位置上
System.out.println(arr[2]);
for(int i=0;i<arr.length;i++) {
if(arr[i]==6) {
System.out.println(i);
}
}
替换:将某个位置的值换成另一个位置的值
arr[2]=199;
System.out.println(arr[2]);
//直接排序
int[] arr= {3,7,12,89,23,45,1,0};
for(int i=0;i<arr.length;i++) {
for(int j=i;j<arr.length;j++) {
if(arr[i]>arr[j]) {
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
System.out.print(arr[i]);
}
System.out.println(Arrays.toString(arr));
//选择排序
int[] arr1= {3,7,12,89,23,45,1,0};
for(int i=0;i<arr1.length;i++) {
int minIndex=i;
for(int j=i;j<arr1.length;j++) {
if(arr1[j]<arr1[minIndex]) {
minIndex=j;
}
}
int temp=arr1[i];
arr1[i]=arr1[minIndex];
arr1[minIndex]=temp;
}
System.out.println(Arrays.toString(arr1));
//冒泡排序
int a[]={3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};
for (int i = 0; i < a.length-1; i++) {
for (int j = 0; j < a.length-1-i; j++) {
if (a[j]>a[j+1]) {
int temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
System.out.println(Arrays.toString(a));
给定一个无重复元素的整数数组nums,请你找出其中没有出现的最小的正整数
进阶: 空间复杂度 O(1),时间复杂度 O(n)
数据范围:
−231≤nums[i]≤231−1
0≤len(nums)≤5∗105
示例1
输入:
[1,0,2]
返回值:
3
public int minNumberDisappeared (int[] nums) {
//定义hash表
int[] hash=new int[500001];
//遍历给我的数组
for(int item:nums){
if(item<0||item>=hash.length){
continue;
}else{
hash[item]++;
}
}
for(int i= 1;i<hash.length;i++){
if(hash[i]==0){
return i;
}
}
return hash.length;
}
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组[2,3,1,0,2,5,3],那么对应的输出是2或者3。存在不合法的输入的话输出-1
数据范围:0≤n≤10000
进阶:时间复杂度O(n) ,空间复杂度O(n)
输入:
[2,3,1,0,2,5,3]
返回值:
2
说明:
2或3都是对的
public int duplicate (int[] numbers) {
// write code here
int[] hash=new int[numbers.length];
for(int item:numbers){
if(hash[item]==0){
hash[item]++;
}else{
return item;
}
}
return -1;
}
输入一个长度为 n 整数数组,数组里面可能含有相同的元素,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前面部分,所有的偶数位于数组的后面部分,对奇数和奇数,偶数和偶数之间的相对位置不做要求,但是时间复杂度和空间复杂度必须如下要求。
数据范围:0≤n≤50000,数组中每个数的值 0≤val≤10000
要求:时间复杂度 O(n),空间复杂度 O(1)
示例1
输入:
[1,2,3,4]
返回值:
[1,3,2,4]
说明:
[3,1,2,4]或者[3,1,4,2]也是正确答案
public int[] reOrderArrayTwo (int[] array) {
// write code here
int[] oddArray=new int[50000];
int[] envArray=new int[50000];
int oddIndex=0;
int envIndex=0;
for(int item:array){
//判断奇偶
if((item & 1)==1){
oddArray[oddIndex++]=item;
}else{
envArray[envIndex++]=item;
}
}
for(int i=0;i<oddIndex;i++){
array[i]=oddArray[i];
}
for(int i=0;i<envIndex;i++){
array[i+oddIndex]=envArray[i];
}
return array;
}
输入一个长度为n的整型数组array,数组中的一个或连续多个整数组成一个子数组,找到一个具有最大和的连续子数组。
1.子数组是连续的,比如[1,3,5,7,9]的子数组有[1,3],[3,5,7]等等,但是[1,3,7]不是子数组
2.如果存在多个最大和的连续子数组,那么返回其中长度最长的,该题数据保证这个最长的只存在一个
3.该题定义的子数组的最小长度为1,不存在为空的子数组,即不存在[]是某个数组的子数组
4.返回的数组不计入空间复杂度计算
数据范围:
1<=n<=105
−100<=a[i]<=100
要求:时间复杂度O(n),空间复杂度O(n)
进阶:时间复杂度O(n),空间复杂度O(1)
[1,-2,3,10,-4,7,2,-5]
返回值:
[3,10,-4,7,2]
说明:
经分析可知,输入数组的子数组[3,10,-4,7,2]可以求得最大和为18,故返回[3,10,-4,7,2]
public int[] FindGreatestSumOfSubArray (int[] array) {
if (array.length == 1) {
return array;
}
// write code here
//字串的开始索引 默认从0开始
int low = 0;
//字串的结束索引
int high = 0;
//字串的和
int sum = array[0];
//当前数组字串的和
int max = sum;
//临时值,记录重新加的时候的
int temp = 0;
for (int i = 1; i < array.length; i++) {
//字串加上数组的当前值后,比没加上的要大,则加上该值。
if (sum + array[i] >= array[i]) {
//计算和
sum += array[i];
} else {
//加上之后还比这个值要小,字串直接从这个点开始,继续比较之后的和
sum = array[i];
temp = i;
}
//加上该数组的值后,和比最大记录和要大,移动high指针到当前数的数组下标
if (sum >= max) {
//记录新的最大值
max = sum;
//移动最大字串的结束位置。
high = i;
//记录字串开始的位置
low = temp;
}
}
int[] res = new int[high - low + 1];
for (int i = 0; i < high - low + 1; i++) {
res[i] = array[i + low];
}
return res;
}
二维数组
int[][] arrays= {
{1,2,3},
{4,5,6},
{7,8,9}
};//静态初始化过程.
int[][] arr=new int[6][];//动态初始化 第二个中括号内的值可省略但第一个不可省略
遍历
for(int i=0;i<arrays.length;i++) {
for(int j=0;j<arrays[i].length;j++) {
System.out.print(arrays[i][j]+" ");
}
System.out.println();
}
有一个NxN整数矩阵,请编写一个算法,将矩阵顺时针旋转90度。
给定一个NxN的矩阵,和矩阵的阶数N,请返回旋转后的NxN矩阵。
public int[][] rotateMatrix (int[][] mat, int n) {
// write code here
int[][] res=new int[n][n];
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
res[j][n-i-1]=mat[i][j];
}
}
return res;
}
给定一个大小为 n*m 的矩阵,请以对角线遍历并返回遍历结果
public int[] diagonalOrder (int[][] mat) {
// write code here
int[] res=new int[mat.length*mat[0].length];
int x=0;
int n=mat.length+mat[0].length-1;
for(int i=0;i<n;i++){
if((i&1)==1){
for(int j=0;j<=i;j++){
if(j>=0&&j<mat.length&&i-j>=0&&i-j<mat[j].length){
res[x]=mat[j][i-j];
x++;
}
}
}else{
for(int j=0;j<=i;j++){
if(i-j>=0&&i-j<mat.length&&j>=0&&j<mat[i-j].length){
res[x]=mat[i-j][j];
x++;
}
}
}
}
return res;
}
在 4x4 的棋盘上摆满了黑白棋子,黑白两色棋子的位置和数目随机,其中0代表白色,1代表黑色;左上角坐标为 (1,1) ,右下角坐标为 (4,4) 。
现在依次有一些翻转操作,要对以给定翻转坐标(x,y)(也即第x行第y列)为中心的上下左右四个棋子的颜色进行翻转。
给定两个数组 A 和 f ,分别代表 初始棋盘 和 哪些要进行翻转的位置(x,y) ,请返回经过所有翻转操作后的棋盘。
例如输入[[0,0,1,1],[1,0,1,0],[0,1,1,0],[0,0,1,0]],[[2,2],[3,3],[4,4]]时,初始键盘如下图所示:
对应的输出为[[0,1,1,1],[0,0,1,0],[0,1,1,0],[0,0,1,0]],如下图所示:
public int[][] flipChess (int[][] A, int[][] f) {
// write code here
for(int[] item:f){
int r=item[0]-1;
int c=item[1]-1;
//上:A[r-1][c]
//下;A[r-1][c]
//左;A[r][c-1]
//右:A[r][c+1]
if(r-1>=0){
A[r-1][c]=1-A[r-1][c];
}
if(r+1<A.length){
A[r+1][c]=1-A[r+1][c];
}
if(c-1>=0){
A[r][c-1]=1-A[r][c-1];
}
if(c+1<A[r].length){
A[r][c+1]=1-A[r][c+1];
}
}
return A;
}
给定一个非负整数 num ,生成杨辉三角的前 num 行。
杨辉三角中,每个数是左上方和右上方的数之和。
数据范围: 1≤num≤30
例如当输入为4时,对应的返回值为[[1],[1,1],[1,2,1],[1,3,3,1]],打印结果如下图所示:
public int[][] generate (int num) {
// write code here
int[][] arr=new int[num][];
for(int i=0;i<num;i++){
arr[i]=new int[i+1];
for(int j=0;j<arr[i].length;j++){
arr[i][j]=1;
}
for(int j=1;j<arr[i].length-1;j++){
arr[i][j]=arr[i-1][j-1]+arr[i-1][j];
}
}
return arr;
}
给定两个 nn 的矩阵 A 和 B ,求 AB 。
public int[][] solve (int[][] a, int[][] b) {
int n = a.length;
int[][] res = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
res[i][j] += a[i][k] * b[k][j];
}
}
}
return res;
}
给一个长度为 n 的数组,数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
public int MoreThanHalfNum_Solution (int[] numbers) {
// write code here
int index=0;
int[] arr=new int[50001];
if(numbers.length==1){
return numbers[0];
}else{
for(int i=0;i<numbers.length;i++){
index=numbers[i];
arr[index]=arr[index]+1;
if(arr[index]>numbers.length/2){
return index;
}
}
}
return 0;
}