C
重排链表
public void reorderList(ListNode head){
if(head == null||head.next == null||head.next.next == null){
return;
}
ListNode fast = head;
ListNode slow = head;
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
}
ListNode second = slow.next;
slow.next = null;
second = rever(second);
//merge(head, second);
head = merge(head, second, 0);
}
public void merge1(ListNode l1,ListNode l2){
//注意这里的合并
ListNode tem = new ListNode(0);
while(l2 != null){
tem = l2.next;
l2.next = l1.next;
l1.next = l2;
l1 = l2.next;
l2 = tem;
}
}
//这种用递归的方法要稍微慢一些
public ListNode merge(ListNode l1,ListNode l2,int flag){
if(l1 == null || l2 == null){
return l1 == null?l2:l1;
}else{
if(flag ==0){
flag = 1;
l1.next = merge(l1.next, l2,flag);
return l1;
}else{
flag = 0;
l2.next = merge(l1, l2.next, flag);
return l2;
}
}
}
public ListNode rever(ListNode l1){
if(l1 == null||l1.next == null){
return l1;
}else{
ListNode cur = rever(l1.next);
l1.next.next = l1;
l1.next = null;
return cur;
}
}
F
反转链表
public ListNode reverseList(ListNode head){
if(head == null||head.next == null){
return head;
}else{
//假装head.next已经是最后一个了就好理解了
ListNode cur = reverseList(head.next);
head.next.next = head;
head.next = null;
return cur;
}
}
反转链表2
ListNode next;
public ListNode reverseBetween(ListNode head, int m, int n) {
if(head == null||m==n){
return head;
}else{
if(m==1){
return reversen(head,n);
}else{
//head每next一次其实,m和n都会相对减少1
ListNode ans = reverseBetween(head, m-1, n-1);
head.next = ans;
return head;
}
}
}
public ListNode reversen(ListNode head,int n){
if(n==1){
next = head.next;//记录下这段要反转的链表段后面的这个节点,以便于下面接上
return head;
}else{
ListNode cur = reversen(head.next, n-1);
head.next.next = head;
head.next = next;//注意这里和经典的反转链表不同的地方 不能写成null,因为会断掉
return cur;
}
}
分割链表
public ListNode partition1(ListNode head, int x) {
//还有另外一种的头插法需要掌握
if(head == null||head.next == null){
return head;
}else{
ListNode low = new ListNode(0);
low.next = head;
ListNode ans = low;
ListNode high = new ListNode(0);
ListNode flag = high;
while(head != null){
if(head.val < x){
low.next = head;
low = low.next;
}else{
high.next = head;
high = high.next;
}
head = head.next;
}
high.next = null;//这一步不能去掉,不然会有环产生
low.next = flag.next;
return ans.next;
}
}
public ListNode partition(ListNode head, int x) {
if(head == null || head.next == null){
return head;
}else{
ListNode first = new ListNode(-1);
first.next = head;
ListNode cur = head.next;
ListNode tail = head;
ListNode next = null;
while(cur != null){
next = cur.next;
if(cur.val < x){
//头插法
cur.next = first.next;
first.next = cur;
}else{
tail.next = cur;
tail = tail.next;
}
cur = next;
}
tail.next = null;
return first.next;
}
}
复杂链表的复制
public Node copyRandomList(Node head) {
if(head == null){
return head;
}
HashMap<Node, Node> map = new HashMap<>();
map.put(null, null);//注意这句不能没有,因为有的节点的nexts是null
Node tem = head;
while(tem != null){
map.put(tem, new Node(tem.val));
tem = tem.next;
}
tem = head;
while(tem != null){
//重点
map.get(tem).next = map.get(tem.next);
map.get(tem).random = map.get(tem.random);
tem = tem.next;
}
return map.get(head);
}
H
合并两个排序的链表
public ListNode mergeTwoLists(ListNode l1,ListNode l2){
if(l1 == null || l2 == null){
return l1 == null?l2:l1;
}else{
if(l1.val > l2.val){
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}else{
l1.next = mergeTwoLists(l1.next, l2);
return l1;
}
}
}
合并K个升序链表
public ListNode mergeKLists(ListNode[] lists){
if(lists.length == 0||lists == null){
return null;
}else{
return solve(lists, 0, lists.length - 1);
}
}
public ListNode solve(ListNode[] list,int left,int right) {
if(left == right){
return list[left];
}
//分制思想 可以类比归并排序
int mid = left + (right -left)/2;
return merge(solve(list, left, mid), solve(list, mid+1, right));
}
public ListNode merge(ListNode l1,ListNode l2){
if(l1 == null || l2 == null){
return l1 == null ? l2 : l1;
}else{
if(l1.val > l2.val){
l2.next = merge(l2.next, l1);
return l2;
}else{
l1.next = merge(l1.next, l2);
return l1;
}
}
}
环形链表2
public ListNode detectCycle(ListNode head){
if(head == null || head .next == null){
return null;
}
ListNode fast = head;
ListNode slow = head;
while(true){
if(fast == null||fast.next == null){
return null;
}
fast = fast.next.next;
slow = slow.next;
if(fast == slow){
break;
}
}
fast = head;
while(fast != slow){
fast = fast.next;
slow = slow.next;
}
return slow;
}
回文链表
public boolean isPalindrome1(ListNode head) {
if(head == null||head.next == null){
return true;
}else{
ListNode fast = head;
ListNode slow = head;
while(fast != null){
if(fast.next == null){
fast = fast.next;
}else{
slow = slow.next;
fast = fast.next.next;
}
}
slow = reverse(slow);
fast = head;
while(fast != null && slow != null ){
if(fast.val != slow.val){
return false;
}
fast = fast.next;
slow = slow.next;
}
return true;
}
}
public ListNode reverse(ListNode head){
if(head ==null || head.next == null){
return head;
}else{
ListNode cur = reverse(head.next);
head.next.next = head;
head.next = null;
return cur;
}
}
//--------------------------------------
//一个更快的方法,指针边跑边翻转
public boolean isPalindrome(ListNode head) {
if(head == null || head.next == null){
return true;
}
ListNode slow = head;
ListNode fast = head;
ListNode prenode = null;
ListNode tem = head;
while(fast != null && fast.next != null){
tem = slow;
slow = slow.next;
fast = fast.next.next;
tem.next = prenode;
prenode = tem;
}
if(fast != null){
slow = slow.next;
}
while(slow != null && tem != null){
if(slow.val != tem.val){
return false;
}
slow = slow.next;
tem = tem.next;
}
return true;
}
J
奇偶链表
public ListNode oddEvenList(ListNode head) {
if(head == null || head.next == null||head.next.next == null){
return head;
}else {
ListNode sin = head;
ListNode dou = head;
ListNode temp = sin.next;
while(dou!= null&&dou.next != null){
ListNode tem = sin.next;
sin.next = sin.next.next;
dou = tem;
dou.next = dou.next.next;
sin = sin.next;
dou = dou.next;
}
sin.next = temp;
return head;
}
}
K
K个一组翻转链表
public ListNode reverseKGroup(ListNode head, int k) {
if(head == null || k == 0 || k == 1){
return head;
}else{
ListNode tem = head;
for(int i = 1;i < k;i++){
if(tem.next == null){
//注意这里判断是tem.next,因为本轮就是要把tem变tem.next
return head;
}else{
tem = tem.next;
}
}
ListNode temnext = tem.next;
ListNode ans = reverse(head, tem);
head.next = reverseKGroup(temnext, k);
return ans;
}
}
public ListNode reverse(ListNode head,ListNode right) {
if(head == right){
return head;
}else{
ListNode cur = reverse(head.next, right);
head.next.next = head;
head.next = null;
return cur;
}
}
L
链表随机节点
public class Solution{
ListNode head;
public Solution(ListNode head) {
this.head = head;
}
public int getRandom() {
int ans = 0;
int count = 0;
ListNode node = head;
while(node != null){
count++;
Random random = new Random();
if(random.nextInt(count) == 0){
ans = node.val;
}
node= node.next;
}
return ans;
}
}
链表中的下一个更大节点
public int[] nextLargerNodes(ListNode head) {
if(head == null){
return null;
}else{
int length = 0;
ListNode tem = head;
while(tem != null){
length++;
tem = tem.next;
}
tem = head;
int[] arr = new int[length];
int[] ans = new int[length];
Stack<Integer> stack = new Stack<>();
int i = 0;
while(tem != null){
arr[i] = tem.val;
if(stack.isEmpty()){
stack.push(i);
}else{
while(!stack.isEmpty()&&arr[i] > arr[stack.peek()]){
ans[stack.peek()] = arr[i];
stack.pop();
}
stack.push(i);
}
i++;//这里不能忘了
tem = tem.next;
}
return ans;
}
}
链表组件
public int numComponents(ListNode head, int[] G) {
if(head == null){
return 0;
}
HashSet<Integer> set = new HashSet<>();
for(int i = 0;i < G.length;i++){
set.add(G[i]);
}
int ans = 0;
while(head != null){
if(set.contains(head.val)||(head.next != null && !set.contains(head.next))){
ans++;
}
head = head.next;
}
return ans;
}
两数相加
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode ans = new ListNode(-1);
int flag = 0;
ListNode ansr = ans;
while(l1 != null || l2 != null){
if(l1 == null){
ans.next = new ListNode(l2.val + flag);
l2 = l2.next;
}else if(l2 == null){
ans.next = new ListNode(l1.val + flag);
l1 = l1.next;
}else{
ans.next = new ListNode(l1.val + l2.val + flag);
l1 = l1.next;
l2 = l2.next;
}
flag = ans.next.val / 10;
ans.next.val %= 10;
ans = ans.next;
}
if(flag == 1){
ans.next = new ListNode(1);
}else{
ans.next = null;
}
return ansr.next;
}
X
旋转链表
先变成环再截断就是了
旋转链表
public ListNode rotateRight(ListNode head,int k){
if(head == null||k == 0||head.next == null){
return head;
}
ListNode cur = head;
int i = 1;
while(cur.next!= null){
cur = cur.next;
i++;
}
k %= i;
cur.next = head;
i = i - k - 1;
cur = head;
while(i != 0){
cur = cur.next;
i--;
}
head = cur.next;
cur.next = null;
return head;
}
Y
移除链表元素
用递归的方法
移除链表元素
public ListNode removeElements(ListNode head,int val){
if(head == null||(head.next == null && head.val == val)){
return null;
}else{
if(head.val == val){
return removeElements(head.next, val);
}else{
head.next = removeElements(head.next, val);
return head;
}
}
}