一:链表的合并
思路分析1(双指针解法)
1:定义两个指针遍历l1,l2分别指向第一条链表的头结点list1和第二条链表的头结点list2;
2:定义一个空节点preNode,用于连接两条有序链表,定义一个结果指针指向空节点
3.1:当两条链表的头结点都为空是直接返回null即可
3.2:当两条链表都不为空时,循环比较节点值的大小,将值较小的节点挂载到结果指针之后,并将结果指针后移
3.3:当退出循环时,两条链表有一条为空时,将不为空的链表的所有节点挂载到结果指针之后即可
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
//定义一个头结点的前驱节点
ListNode preNode=new ListNode(-1);
//定义一个指针指向头结点的前驱结点,用于遍历新生成的链表
ListNode resNode = preNode;
// 定义一个指针l1指向头结点list1
ListNode l1=list1;
// 定义一个指针l2指向头结点list2
ListNode l2=list2;
//如果第一个条链表的头结点为空,那么直接返回第二条链表的头结点即可
if(list1==null){
return list2;
}
如果第二个条链表的头结点为空,那么直接返回第一条链表的头结点即可
if(list2==null){
return list1;
}
//l1 , l2有一个为空(即有一条链表遍历完毕之后)就退出循环
while(l1!=null && l2!=null){
//当第一条链表的头结点小于第二条链表的头结点时
if(l1.val<l2.val){
//将l1挂载到头结点的前驱结点之后
resNode.next=l1;
//指向第一条链表的指针后移
l1=l1.next;
}
else {
//否则l2挂载到前驱节点之后
resNode.next=l2;
//指针后移
l2=l2.next;
}
//每循环一次,就将将指向前驱节点的指针后移
resNode=resNode.next;
}
//当退出循环时,即两条链表至少有一条为空
//如果第一条链表遍历完毕,为空时
if(l1==null){
//将第二条链表后的所有节点挂载到结果指针上
resNode.next=l2;
}
//如果第二条链表遍历完毕,为空时
if(l2==null){
//将第一条链表后的所有节点挂载到结果指针上
resNode.next=l1;
}
return preNode.next;
}
}
思路分析2(递归解法)
1:先进行头结点是否为空的判断
2:比较两条链表头结点值的大小,如果list1<list2,将list2指向list1,并递归的开始比较list2与第一条链表去除掉list1之后的所有节点
3:如果list2<list1,将list1指向list2,并递归的开始比较list1与第二条链表去除掉list2之后的所有节点
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
if(list1==null){
return list2;
}
if(list2==null){
return list1;
}
if(list1.val>=list2.val){
list2.next=mergeTwoLists(list1,list2.next);
return list2;
}
else{
list1.next=mergeTwoLists(list1.next,list2);
return list1;
}
}
}
二:数组的合并
思路分析:
1:需要建立一个新数组,大小为m+n;并定义nums1数组的下标变量nums1Index,nums2数组的下标变量nums2Index,新数组的下标变量index
2.1:当nums1数组中的m个元素全部取完时,将nums2数组中的所有元素全部添加到新数组中
2.2:当nums2数组中的n个元素全部取完时,将nums1数组中的所有元素全部添加到新数组中
2.3:如果nums1数组中第nums1Index个元素小于nums2数组中第nums2Index个元素时,将较小的值添加的新数组中,nums1Index后移
2.4:如果nums2数组中第nums2Index个元素小于nums1数组中第nums1Index个元素时,将较小的值添加的新数组中,nums2Index后移
注意:一定要先判断nums1数组和nums2数组是否全部取完,再比较两个数组内元素大小。
如果先判断两个数组内元素大小的话,如nums1 = [1,2,3,0,0,0],就会把3后面的0,0,0输入到新数组中,判断不了nums2数组中剩下的元素
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
int k=m+n;
//定义一个新数组,用于存储排序后的数组元素,数组大小为m+n
int[] newArr=new int[k];
int nums1Index=0;
int nums2Index=0;
//index指向新数组的第一个元素,下标为0
for(int index=0;index<k;index++){
//当nums1数组中所有元素取完时,将nums2数组中的所有元素添加的新数组中
if(nums1Index >= m){
newArr[index]=nums2[nums2Index++];
}
//当nums2数组中所有元素取完时,将nums1数组中的所有元素添加的新数组中
else if(nums2Index >= n){
newArr[index]=nums1[nums1Index++];
}
//当nums1数组元素小于nums2数组元素时
else if(nums1[nums1Index]<nums2[nums2Index]){
//把较小值添加到新数组中去
newArr[index]=nums1[nums1Index];
//并将指针后移
nums1Index++;
}
// 当nums2数组元素小于nums1数组元素时
else {
newArr[index]=nums2[nums2Index];
nums2Index++;
}
}
//题目中要求存储到nums1数组中
//遍历新数组中的所有元素,取出并存放到nums1中
for(int i=0;i<k;i++){
nums1[i]=newArr[i];
}
}
}