💎💎💎💎💎
更多资源链接,欢迎访问作者gitee仓库:https://gitee.com/fanggaolei/learning-notes-warehouse/tree/master
哔哩哔哩算法题视频讲解:Java初级算法合集
1.删除链表中的节点
class Solution {
public void deleteNode(ListNode node) {
node.val=node.next.val;
node.next=node.next.next;
}
}
2.删除链表的倒数第N个节点
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode pre = head;
int last = length(head) - n;
//如果last等于0表示删除的是头结点
if (last == 0)
return head.next;
//这里首先要找到要删除链表的前一个结点
for (int i = 0; i < last - 1; i++) {
pre = pre.next;
}
//然后让前一个结点的next指向要删除节点的next
pre.next = pre.next.next;
return head;
}
//求链表的长度
private int length(ListNode head) {
int len = 0;
while (head != null) {
len++;
head = head.next;
}
return len;
}
3.反转链表
思路一:表节点一个个入栈,当全部入栈完之后再一个个出栈,出栈的时候在把出栈的结点串成一个新的链表
class Solution {
public ListNode reverseList(ListNode head) {
//将链表放入栈中
Stack<ListNode> stack=new Stack<>();
while(head!=null){
stack.push(head);
head=head.next;
}
ListNode tmp=new ListNode(0);
ListNode tmp1=tmp;
while(!stack.isEmpty()){
tmp1.next=stack.pop();
tmp1=tmp1.next;
}
tmp1.next=null;
return tmp.next;
}
}
思路二:
public ListNode reverseList(ListNode head) {
//新链表
ListNode newHead = null;
while (head != null) {
ListNode temp = head.next;
head.next = newHead;
newHead = head;
head = temp;
}
//返回新链表
return newHead;
}
4.合并两个有序链表
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
if(list1==null){
return list2;
}
if(list2==null){
return list1;
}
ListNode tmp=new ListNode(0);
ListNode tmp1=tmp;
while(list1!=null&&list2!=null){
if(list1.val<=list2.val){
tmp1.next=list1;
list1=list1.next;
}else{
tmp1.next=list2;
list2=list2.next;
}
tmp1=tmp1.next;
}
tmp1.next=list1==null?list2:list1;
return tmp.next;
}
}
5.回文链表
思路一:求链表长度找中间值
class Solution {
public boolean isPalindrome(ListNode head) {
//定义慢指针
ListNode fast=head;
//求出链表长度
int length=length(head);
//找到中点
if(length%2==0){
for (int i = 0; i < length/2; i++) {
fast=fast.next;
}
}else {
for (int i = 0; i < length / 2 + 1; i++) {
fast = fast.next;
}
}
//反转后半部分
fast=reversal(fast);
while (fast!=null&&head!=null){
if(fast.val==head.val){
fast=fast.next;
head=head.next;
}else {
return false;
}
}
return true;
}
public int length(ListNode head){
int len=0;
while(head!=null){
head=head.next;
len++;
}
return len;
}
public ListNode reversal(ListNode node){
ListNode tmp=null;
while(node!=null){
ListNode tmp1=node.next;
node.next=tmp;
tmp=node;
node=tmp1;
}
return tmp;
}
}
思路二:快慢指针找中间值
public boolean isPalindrome(ListNode head) {
ListNode fast = head, slow = head;
//通过快慢指针找到中点
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
//如果fast不为空,说明链表的长度是奇数个
if (fast != null) {
slow = slow.next;
}
//反转后半部分链表
slow = reverse(slow);
fast = head;
while (slow != null) {
//然后比较,判断节点值是否相等
if (fast.val != slow.val)
return false;
fast = fast.next;
slow = slow.next;
}
return true;
}
//反转链表
public ListNode reverse(ListNode head) {
ListNode prev = null;
while (head != null) {
ListNode next = head.next;
head.next = prev;
prev = head;
head = next;
}
return prev;
}
6.环形链表
思路一:快慢指针
public class Solution {
public boolean hasCycle(ListNode head) {
//快慢两个指针
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (slow == fast)
return true;
}
//否则就是没环
return false;
}
}
2.思路二:存放集合
public boolean hasCycle(ListNode head) {
Set<ListNode> set = new HashSet<>();
while (head != null) {
//如果重复出现说明有环
if (set.contains(head))
return true;
//否则就把当前节点加入到集合中
set.add(head);
head = head.next;
}
return false;
}