使用双指针
剑指 Offer 25. 合并两个排序的链表
https://leetcode-cn.com/problems/he-bing-liang-ge-pai-xu-de-lian-biao-lcof/submissions/
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
//有空链表返回不空链表即可
if(l1==null || l2==null){
return l1!=null?l1:l2;
}
ListNode dummy = new ListNode(0);
ListNode tmp = dummy;
while(l1!=null && l2!=null){
if(l1.val<=l2.val){
tmp.next=l1;
l1=l1.next;
}else{
tmp.next=l2;
l2=l2.next;
}
tmp=tmp.next;
}
//l1为空或l2为空
tmp.next=(l1==null?l2:l1);
return dummy.next;
}
两数相加
https://leetcode-cn.com/problems/add-two-numbers/
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
int carry=0;
ListNode head = new ListNode(-1), cur=head;
while(l1!=null || l2!=null){
int n1 = l1==null? 0:l1.val;
int n2 = l2==null? 0:l2.val;
//计算节点相加后的结果
int sum =n1+n2+carry;
//更新进位
carry = sum/10;
//结果储存在新链表中
cur.next=new ListNode(sum%10);
cur=cur.next;
//更新双指针
if(l1!=null) l1=l1.next;
if(l2!=null) l2=l2.next;
}
if(carry>0){
cur.next=new ListNode(carry);
}
return head.next;
}
复杂度分析
时间复杂度:
O
(
m
a
x
(
m
,
n
)
)
O(max(m,n))
O(max(m,n)),其中 m,n 为两个链表的长度。我们要遍历两个链表的全部位置,而处理每个位置只需要
O
(
1
)
O(1)
O(1) 的时间。
空间复杂度:
O
(
m
a
x
(
m
,
n
)
)
O(max(m,n))
O(max(m,n))。答案链表的长度最多为较长链表的长度 +1。
个人遇到的问题:
1、处理链表节点为null的方式:int n1 = l1==null? 0:l1.val
2、对于整型数据 sum/10 为向下取整
26. 删除排序数组中的重复项
https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array/
public int removeDuplicates(int[] nums) {
if(nums.length==0) return 0;
//使用快慢指针
//由于数组已经排序,所以重复的元素连在一起
int slow=0, fast=0;
while(fast<nums.length){
//当找到新元素后,用nums[0...slow]维护
if(nums[slow]!=nums[fast]){
slow++;
nums[slow]=nums[fast];
}
fast++;
}
return slow+1;
}
430. 扁平化多级双向链表(中)
https://leetcode-cn.com/problems/flatten-a-multilevel-doubly-linked-list/
1---2---3---4---5---6--NULL
|
7---8---9---10--NULL
|
11--12--NULL
可转化为二叉树的先序遍历求解
public Node flatten(Node head) {
if (head==null) return null;
Node dummy=new Node(-1,null,head,null);
//定义递归函数,返回去序列化后的尾部指针(此处不需要返回值)
flatten_dfs(dummy, head);
dummy.next.prev=null;
return dummy.next;
}
public Node flatten_dfs(Node pre, Node cur){
if(cur==null) return pre;
//前序遍历
pre.next=cur; //目的是将子链表的尾节点与下一节点链接
cur.prev=pre;
Node curNext=cur.next;
Node tail = flatten_dfs(cur,cur.child); //cur.child看做左子树
cur.child = null;
return flatten_dfs(tail,curNext); //cur.next看做右子树
}
二叉树递归遍历框架
void traverse(TreeNode root) {
// 前序遍历
traverse(root.left)
// 中序遍历
traverse(root.right)
// 后序遍历
}
https://mp.weixin.qq.com/s/ZYaXOSVM3YBIeRWm7E_jcQ
138. 复制带随机指针的链表(中)
https://leetcode-cn.com/leetbook/read/linked-list/fdi26/
对链表进行一次遍历操作,并用哈希映射来储存辅助信息
HashMap<Node,Node> map = new HashMap();
public Node copyRandomList(Node head) {
//方法一,使用哈希Map记录节点是否被深拷贝
if (head==null) return null;
Node oldhead=head;
Node newhead=new Node(head.val,null,null);
this.map.put(head,newhead);
//进行迭代
while(oldhead!=null){
newhead.random = this.getClonedNode(oldhead.random);
newhead.next = this.getClonedNode(oldhead.next);
newhead=newhead.next;
oldhead=oldhead.next;
}
return this.map.get(head);
}
public Node getClonedNode(Node node){
//返回一个拷贝节点,并记录在哈希表中
if(node==null) return null;
if(this.map.containsKey(node)){
return this.map.get(node);
} else {
this.map.put(node, new Node(node.val,null,null));
} return this.map.get(node);
}