记录的都是我不清楚的知识点,仅供自己参考。
二维数组在内存空间地址中的连续性:C++连续,Java不连续
Java定义二维动态数组(总是记不住):ArrayList> list = new ArrayList
>();
关键点:左闭右开区间还是左闭右闭区间。while循环里是合法区间,循环时不包含上一次循环的区间。
C++移除数组元素库函数(刷题时不要直接用库函数):
erase() 时间复杂度:o(n)
双指针法移除数组元素:https://www.bilibili.com/video/BV12A4y1Z7LP/?vd_source=5c915cf57c18c90b48105ad42b2a7ef9&t=368.0
// 时间复杂度:O(n)
// 空间复杂度:O(1)
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int slowIndex = 0;
for (int fastIndex = 0; fastIndex < nums.size(); fastIndex++) {
if (val != nums[fastIndex]) {
nums[slowIndex++] = nums[fastIndex];
}
}
return slowIndex;
}
};
数组常用函数:
数组排序:Arrays.sort(arr, new Comparator(){})
数组转换成字符串:Arrays.toString(arr)
注:C++在删除链表元素时,需要对删除元素进行手动释放:delete()
头结点与中间节点的删除方式不一样。
头结点删除方式:head = head->next;
中间节点删除方式:p->next = q->next;
所以有两种方法删除。
法一:先删除头结点,再删除中间节点
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
// 删除头结点
while (head != NULL && head->val == val) { // 注意这里不是if
ListNode* tmp = head;
head = head->next;
delete tmp;
}
// 删除非头结点
ListNode* cur = head;
while (cur != NULL && cur->next!= NULL) {
if (cur->next->val == val) {
ListNode* tmp = cur->next;
cur->next = cur->next->next;
delete tmp;
} else {
cur = cur->next;
}
}
return head;
}
};
法二:额外增加一个数值为空的头结点指向当前头结点,将头结点与中间节点的删除方式统一起来。
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode* dummyHead = new ListNode(0); // 设置一个虚拟头结点
dummyHead->next = head; // 将虚拟头结点指向head,这样方面后面做删除操作
ListNode* cur = dummyHead;
while (cur->next != NULL) {
if(cur->next->val == val) {
ListNode* tmp = cur->next;
cur->next = cur->next->next;
delete tmp;
} else {
cur = cur->next;
}
}
head = dummyHead->next;
delete dummyHead;
return head;
}
};
创建节点结构体
public class ListNode<E> {
public E val;
public ListNode next;
ListNode(E x)
{
this.val = x;
this.next = null;
}
}
链表操作
package Link;
import java.util.LinkedList;
public class MyLinkedList<E> {
//头结点
public ListNode<E> head = null;
//头插法插入新节点
public void addFirst(E data){
ListNode<E> node = new ListNode<>(data);
if(head==null){
head = node;
}else{
node.next = head;
head = node;
}
}
//尾插法插入新节点
public void addLast(E data){
ListNode<E> node = new ListNode<>(data);
if(head==null){
head = node;
}else{
ListNode<E> p = head;
while(p.next!=null){
p = p.next;
}
p.next = node;
}
}
//任意位置插入新节点
public void addAny(E data, int num){
//判断num范围
if(num<0||num>this.size()){
//Java异常还没学,学完了修改
System.out.println("异常,插入索引错误");
}else if(num==0){
ListNode<E> q = new ListNode<>(data);
q.next = head;
head = q;
}else{
ListNode<E> q = new ListNode<>(data);
ListNode<E> p = head;
while(num--!=1){
p = p.next;
}
q.next = p.next;
p.next = q;
}
}
//打印链表
public void display(){
//链表空
if(head==null){
System.out.println("链表为空");
}
ListNode<E> p = head;
while(p!=null){
System.out.println(p.val);
p = p.next;
}
}
//判断节点是否存在
public boolean isInstance(E data){
ListNode<E> p = head;
while(p!=null){
if(p.val==data){
return true;
}
p = p.next;
}
return false;
}
//查找节点,返回下标
public int find(E data){
if(this.isInstance(data)){
ListNode<E> p = head;
int count = 0;
while(p!=null){
if(p.val==data){
return count;
}
count++;
p = p.next;
}
}
return -1;
}
//删除第一个关键字为data的链表节点并返回元素
public void remove(E data){
ListNode<E> p = head;
//头结点需特判
if(head!=null&&head.val==data){
head = head.next;
return;
}
while(p!=null&&p.next!=null){
if(p.next.val==data){
p.next = p.next.next;
return;
}
p = p.next;
}
}
//删除所有关键字为key的节点
public void removeAll(E data){
ListNode<E> dummyHead = new ListNode<>(data);
dummyHead.next = head;
ListNode<E> p = dummyHead;
while(p.next!=null){
if(p.next.val==data){
p.next = p.next.next;
}else{
p = p.next;
}
}
head = dummyHead.next;
}
//删除指定位置节点
public E removeAt(int num){
//判断num范围
if(num<0||num>this.size()-1){
System.out.println("索引异常");
return null;
}else if(num==0){
ListNode<E> q = head;
head = head.next;
return q.val;
}else {
ListNode<E> p = head;
while (num-- != 1) {
p = p.next;
}
ListNode<E> q = p.next;
p.next = p.next.next;
return q.val;
}
}
//获取指定位置节点元素
public E get(int num){
if(num<0||num>this.size()-1){
System.out.println("索引异常");
return null;
}else {
ListNode<E> p = head;
while (num-- != 0) {
p = p.next;
}
return p.val;
}
}
//链表长度
public int size(){
int count = 0;
ListNode p = head;
while(p!=null){
p = p.next;
count++;
}
return count;
}
//清空链表
public void clear(){
//链表本身为空
head = null;
}
}
测试
package Link;
import java.util.LinkedList;
public class main {
public static void main(String[] args) {
MyLinkedList<Integer> ll = new MyLinkedList<>();
// ll.display();
ll.addLast(0);
ll.addLast(1);
ll.addLast(2);
// ll.display();
System.out.println(ll.isInstance(100));
ll.addAny(100, 3);
System.out.println(ll.isInstance(100));
ll.display();
System.out.println("size:"+ll.size());
System.out.println(ll.find(101));
System.out.println("-------------------");
ll.remove(100);
ll.remove(0);
ll.display();
System.out.println("-----------------");
ll.addLast(0);
ll.addLast(0);
ll.addLast(0);
ll.addLast(0);
ll.addLast(1);
ll.display();
System.out.println("-----------------");
ll.removeAll(100);
ll.display();
System.out.println("-----------------");
System.out.println("删除的是:"+ll.removeAt(5));
ll.display();
System.out.println("-----------------");
System.out.println(ll.get(0));
System.out.println("-----------------");
ll.clear();
ll.display();
}
}
用哈希法的前提:元素是否出现过
Java注意事项:
Java的字符串不能原地修改,可以重新创建一个StringBuilder,StringBuilder可以修改
sb.append(" aaa") 添加字符串
sb.reverse() 字符串反转
sb.toString() 把StringBuilder类型转换为String类型
sb.charAt(i) 返回第i个位置的字符
sb.setCharAt(i, u) 将第i个位置的字符设置为u
//字符转换为字符串
String str = String.valueOf(Char);
//字符串转换为字符数组
char[] c = s.toCharArray();
//字符数组转换为字符串
String s = "abcde";
String str = s.substring(0,2);//左闭右开,此时str的值为ab
不像Java,C++字符串可以用数组索引获取字符串中的字符,也可以修改字符串中的字符
扩充字符串大小:s.resize(k) k表示字符串长度
KMP算法这块真是太头大了!刚接触这个概念的小白真是怎么听也听不明白,感觉视频里有很多细节都没有讲清楚,看这个:https://www.cnblogs.com/dusf/p/kmp.html
优先级队列会把队列内元素做一个排序,按一定的优先级顺序出队列。(原理没细看,可以看看源码)
Java 整数和字符串互相转换:
//整数转换为字符串:
String a = " ";
int b = Integer.parseInt(a);
//字符串转换为整数:
int b = 0;
String a = STring.valueOf(b);
Java翻转ArrayList:Collections.reverse(list);
没有返回值,原地翻转列表
Java排序函数:
对数组排序:Arrays.sort(arr);
对列表排序:用列表自带的排序函数
ArrayList
list.sort();
Java的int最大值最小值:
最大值:Integer.MAX_VALUE ,2^31 - 1
最小值:Integer.MIN_VALUE
数组可以作为Java方法的返回值:int[] func(int a, int b){}
调用函数时:int[] arr = func(a, b);
Math常用数学运算
乘方:Math.pow(a, b) a的b次方
开平方:Math.sqrt(double a)