链表与递归
链表
从一道leecode体面中先看
题目:删除链表中等于给定值val的所有元素
示例:
给定:1->2->3->8->4->56->8,val=8
返回:1->2->3->4->56
coding
package arithmetic.recursive;
public class ListNode {
public int val;
public ListNode next;
public ListNode(int val) {
this.val = val;
}
}
package arithmetic.recursive;
public class Solution {
public ListNode removeElements(ListNode head, int val) {
while (head != null && head.val == val){
ListNode delNode = head;
head = head.next;
delNode.next = null;
}
if (head == null){
return null;
}
ListNode prev = head;
while (prev.next != null){
if (prev.next.val == val){
ListNode delNode = prev.next;
prev.next = delNode.next;
delNode.next = null;
}else {
prev = prev.next;
}
}
return head;
}
}
下面我们自己写一个创建链表
package arithmetic.recursive;
public class ListNode {
public int val;
public ListNode next;
public ListNode(int val) {
this.val = val;
}
public ListNode(int[] arr){
if (arr == null || arr.length==0){
throw new IllegalArgumentException("arr can not be empty");
}
this.val = arr[0];
ListNode cur = this;
for (int i=0;i<arr.length;i++){
cur.next = new ListNode(arr[i]);
cur = cur.next;
}
}
@Override
public String toString() {
StringBuilder res = new StringBuilder();
ListNode cur = this;
while (cur!=null){
res.append(cur.val + " ->");
cur = cur.next;
}
res.append("NULL");
return res.toString();
}
}
package arithmetic.recursive;
public class Solution {
public ListNode removeElements(ListNode head, int val) {
while (head != null && head.val == val) {
// ListNode delNode = head;
// head = head.next;
// delNode.next = null;
head = head.next;
}
if (head == null) {
return null;
}
ListNode prev = head;
while (prev.next != null) {
if (prev.next.val == val) {
// ListNode delNode = prev.next;
// prev.next = delNode.next;
// delNode.next = null;
prev.next = prev.next.next;
} else {
prev = prev.next;
}
}
return head;
}
public static void main(String[] args) {
int[] nums = {1, 3, 45, 6, 8, 2, 5, 78, 8};
ListNode head = new ListNode(nums);
System.out.println(head);
System.out.println("--------");
ListNode res = (new Solution()).removeElements(head, 8);
System.out.println(res);
}
}
递归
本质上,将原来的问题,转化为更小的问题
举例:数组求和
coding
package arithmetic.recursive;
public class SUm {
public static int sum(int[] arr) {
return sum(arr, 0);
}
//计算arr[l...n]这个区间内所有数字的和
private static int sum(int[] arr, int l) {
if (l == arr.length) {
return 0;
}
return arr[l] + sum(arr, l + 1);
}
public static void main(String[] args) {
int[] nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
System.out.println(sum(nums));
}
}
链表和递归的关系
链表的天然递归性
用递归解决上面删除元素的问题
`package arithmetic.recursive;
import com.sun.org.apache.bcel.internal.generic.RET;
//使用虚拟头结点
public class Solution3 {
public ListNode removeElements(ListNode head, int val) {
if (head == null) {
return null;
}
// ListNode res = removeElements(head.next, val);
// if (head.val == val){
// return res;
// }else {
// head.next = res;
// return head;
// }
head.next = removeElements(head.next, val);
if (head.val == val) {
return head.next;
} else {
return head;
}
}
public static void main(String[] args) {
int[] nums = {1, 3, 45, 6, 8, 2, 5, 78, 10, 9, 8};
ListNode head = new ListNode(nums);
System.out.println(head);
System.out.println("--------");
ListNode res = (new Solution()).removeElements(head, 8);
System.out.println(res);
}
递归函数的“微观”解读
简化sum函数
递归函数的调用,本质就是函数的调用
只不过是调用自己而已和栈没区别:
关于更多和链表相关的话题
- 关于递归
- 近乎和链表相关的所有操作,都可以使用递归的形式完成
- 建议各位对链表的增删改查进行递归实现