学习不要眼高手低,学习是一点点积累的。即使你现在很菜,坚持学一个学期不会差的!只要花时间学习,每天都是进步的,这些进步可能你现在看不到,但是不要小瞧了积累效应,30天,60天,90天后,你每次都会发生质的变化。
每一个人都要有危机感,就好像你被水刑,有人把你的扔进大缸里面,按着你的头,你不停的挣扎,想要呼吸。每当濒死,他每次都会让你呼一会气,这样就是危机感。生于忧患,死于安乐。
大学四年就像温水泡脚,在舒适区快乐玩耍,等毕业了,就是你把洗脚水喝掉的时候了。
-------------------------------------------------------------------------------------------------------------------博哥语录
目录
16. OJ题目:203. 移除链表元素 - 力扣(LeetCode)
1.选择结构,循环结构
选择结构只进入一个模块
java中自动引入import 只需在输入有提示的时候选即可。也可以手动选alt+回车
import类似于include
java中scanner中的不好的点,必须先输入字符串再输入整形,不然会读取错误。
为啥?因为如果这样
先从键盘上标准输入一串数碰到\n,把输入缓冲区里面的\n前面的拿走,留个\n,然后继续执行读取字符串,读取字符串是读完缓冲区所有,发现有个\n拿走,然后OK了,你啥也没输入,第二行代码执行完了。
else 和最近的if相结合
java中用这种风格
2.Java中不能做switch关系类型的有哪些?
boolean
float
double
long
为什么不能用long?
byte、char、short 类型在编译期默认提升为 int,并使用 int 类型的字节码指令。所以对这些类型使用 switch,其实跟 int 类型是一样的。long不能变为int
switch 支持Sting enum 和剩余的四种小于等于int的(int short char byte)以及他们的包装类
一般少用switch,因为switch很难支持复杂的条件,还有switch虽然支持嵌套,但是很丑,难读。
3.break 和continue
break是跳出当前那一套循环,continue是终止这次循环后面不执行,执行下一次循环。
break必须在循环里面,仅仅一个if里面有break语法错误,循环里面有if ,if里面可以有break
System.exit(0);是退出程序
4.输入和输出(scanner.hasNextInt())
输出sout
输入需要先new一个Scanner对象,里面写System.in然后调用类方法实现输入 Line表示字符串其他正常第一个大写即可
多组输入?
注意多组输入了进入以后while还要输入
5.Java中生成随机数
Java中的最大类型数也要访问类型类才能求得
求素数的优化
注意这里第二个循环的结束条件是j*j<=i 因为当j*j==i的时候可以确定i为平方数一定不为素数,只有走到了最后j*j>i才能确定是素数
求1~100中9出现的次数,注意99出现两次,这里推荐写一个方法来判断
这个方法用来统计一个数中9的个数
6.方法
方法就是C语言里面的函数。可以把方法理解为一个工厂,这个工厂可以重复使用。
我们通常把经常使用的东西做成一个方法,可以重复的使用。
链式访问:用方法/函数的返回值,进行计算和调用
在java中没有函数的声明,不管在main函数的下面还是上面
方法的好处,1.使得代码容易理解。
2.直接调用现有方法开发,不必造轮子
3.代码可以重复使用,高内聚
4.模块化的组织
函数开辟的内存->栈帧,每个函数调用的时候都创建一片栈帧。
java方法return 后面不能再写代码,会报错
for()
{
ret^=i;
}
最后ret=i^………………;(遍历运算i)
*=
/=
+=
也一样
7.Java中交换两个变量
Java中不能直接交换俩变量,因为java中不可以取地址。要去做只能把a和b放在堆上面(a和b变为对象)
Java中可以把俩数放在数组中交换,因为数组实际上是在堆上new出来的,堆中存放的都是地址,比如说类
add(a,b).sout会快速打印
8.方法重载overload
函数形参的类型,数量不同构成重载。与形参的顺序无关。也与返回值无关
为什么会有重载?因为函数的签名不同,签名包括,函数名,参数的类型
继承关系上也有重载
9.Java中字符串比较
用String的包装类,.equals 。其返回值是boolean
10.求二进制中1的个数另两种方法
第一种for循环右移
第二种
注意是无符号右移,因为必须要补0(负数的情况)
第三种,利用算法的性质:
6&5的得到的结果,在二进制的表示形式中少了一个1(从右边开始少)
结论:n%(n-1)的结果是n的二进制右边少了一个1
还有一种由得到十进制每一位而启发来的方法。
十进制的到每一位是%10 再/10 ,而二进制得到每一位也是%2 再/2
缺点是只能计算正数的2进制中1的数目
11.获取一个数的每一位的Java方法
熟悉charAt(字符串的下标) 是String的方法。获取字符串指定下标的元素
熟悉digit(某一字符,N进制数)是Character的方法可以把一个字符转化为N进制的数字
递归方法打印
12.计算一个数长度的方法
String.valueOf(类型) 是将类型转化为String的方法
13.知识
java编译后产生byte 码不是machine code java中char是Unicode编码的两个字节
java中包装类是八大基本类型的扩展的类,String不是包装类
java编译用javac 文件名.java
运行时用java 文件名
1&N:结果要么是0要么是1,取决于N第0位二进制是多少。
N第0位是0则是0 ,第0位是1则是1
0^N还是N ^具有交换律 还有N^N=0
所以说^可以找出一堆数字中仅出现1次的数(其余数出现两次)
14.方法的递归
递归是方法自己调用自己的过程。
递归的前提,不能死递归,要越来越接近终止递归的条件
递归要找到递推公式,难就难在找递推公式
递推相当于数学的数学归纳法,有一个起始条件,然后有一个递推公式
15.^交换两个数
使用异或操作交换两个变量的值是常用的技巧,因为它不需要额外的临时变量。
a^=b
b^=a
a^=b
之后a,b的值被交换
16. OJ题目:203. 移除链表元素 - 力扣(LeetCode)
struct ListNode* removeElements(struct ListNode* head, int val){
struct ListNode* prev=NULL;
struct ListNode* cur=head;
while(cur){
if(cur->val!=val){
prev=cur;
cur=cur->next;
}else{
if(prev==NULL){
head=cur->next;
free(cur);
cur=head;
}else{
prev->next=cur->next;
free(cur);
cur=prev->next;
}
}
}
return head;
}
先把一般情况写出来,
然后再考虑特殊情况,如果先考虑特殊情况容易写错。
17.力扣 反转链表
当用i++作为数组下标结束循环的时候,数组长度为i ,最后下标为i-1
解法1
void swap(struct ListNode*e1,struct ListNode*e2) { int temp=e1->val; e1->val=e2->val; e2->val=temp; } struct ListNode* reverseList(struct ListNode* head){ //用一个数组来储存链表节点的地址 struct ListNode*cur=head; struct ListNode*p[1000000]={0};//初始化为NULL(0) int i=0; while(cur) { p[i++]=cur; cur=cur->next; } //就得到了链表每个元素的地址 //然后通过地址第一个元素的val和最后一个元素的val交换 //写个swap函数 int right=i-1;//长度为i,下标为i-1 int left=0; while(left<right) { swap(p[left++],p[right--]); } return head; }
解法2(双指针)
struct ListNode* reverseList(struct ListNode* head){ struct ListNode*cur=head; struct ListNode* prev=NULL; while(cur) { struct ListNode* temp=cur->next;//先记录cur下一个的位置 cur->next=prev;//反序 //调整cur 和prev prev=cur; cur=temp; //重置头指针,当cur为空的时候,cur的前一个节点就是头 if(cur==NULL) { head=prev; } } return head; }
18.力扣 合并两个有序链表
思路是先找出来头节点(第一个val小的那个)然后找出头的那个链表从第二个开始进行比较,用cur一直指向链表的最后一个节点,找到小于这个节点就用cur->next链接。最后若某个链表遍历完了,就将cur和剩下的没遍历的链接
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2){ struct ListNode* cur1=list1; struct ListNode* cur2=list2; struct ListNode*head=NULL; if(!list1) { return list2; } if(!list2) { return list1; } if(cur1->val>=cur2->val) { head=cur2; cur2=cur2->next; } else { head=cur1; cur1=cur1->next; } struct ListNode*cur=head; while(cur1&&cur2) { if(cur1->val>=cur2->val) { cur->next=cur2; cur=cur2; cur2=cur2->next; } else//cur2大 { cur->next=cur1; cur=cur1; cur1=cur1->next; } } if(!cur1) { cur->next=cur2; } else { cur->next=cur1; } return head; }