链表复习

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

反转链表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个升序链表

合并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

环形链表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个一组翻转链表

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;
			}
		}
	}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值