23.合并k个升序链表
题目描述:给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
思路:利用第21题合并两个升序链表的函数,先合并链表数组的前两个链表,再与第三个合并,以此类推。
代码如下:
/**
* Definition for singly-linked list.
* public class ListNode {
* public int val;
* public ListNode next;
* public ListNode(int val=0, ListNode next=null) {
* this.val = val;
* this.next = next;
* }
* }
*/
public class Solution {
public ListNode MergeKLists(ListNode[] lists) {
if (lists.Length == 0)
return null;
ListNode templ = lists[0];
for (int i = 1; i < lists.Length; i++)
{
templ = MergeTwoLists(templ, lists[i]);
}
return templ;
}
public ListNode MergeTwoLists(ListNode l1, ListNode l2)
{
ListNode p = new ListNode();
ListNode temp = p;
while (l1 != null && l2 != null)
{
if (l1.val > l2.val)
{
temp.next = l2;
l2 = l2.next;
}
else
{
temp.next = l1;
l1 = l1.next;
}
temp = temp.next;
}
if (l1 == null)
temp.next = l2;
if (l2 == null)
temp.next = l1;
return p.next;
}
}
26.删除排序数组中的重复项
题目描述:给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
思路:使用两个索引i和j,j用来遍历数组,i实际上将数组分成了两个部分,前半部分就是不重复的元素,只需将i之后不重复的元素填入即可。
代码如下:
public class Solution
{
public int RemoveDuplicates(int[] nums)
{
int len = nums.Length;
if(len<2)
return len;
int i=0;
for (int j = 1; j < len; j++)
{
if (nums[j] != nums[i])
{
i++;
nums[i] = nums[j];
}
}
return i + 1;
}
}
33.搜索旋转排序数组
题目描述:升序排列的整数数组 nums 在预先未知的某个点上进行了旋转(例如, [0,1,2,4,5,6,7] 经旋转后可能变为 [4,5,6,7,0,1,2] )。
请你在数组中搜索 target ,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。
思路:基本思路是二分查找法,但与普通的二分查找法不同的是,这个数组经过了旋转,所以本题的重点则在于如何确定二分查找法新的查找范围。根据旋转数组的特点,分析得出,本题在普通二分查找法比较中间数与目标数的大小之外(确定接下里需要比较左端的数还是右端的数),还需要比较中间数与端位数的大小(用于判断左边部分(右边部分)是否是有序的),以及目标数与端位数的大小(确定应该在左(右)边继续而二分查找还是另一边),从而确定新的查找范围。
代码如下:
public class Solution
{
public int Search(int[] nums, int target)
{
int l = 0;
int r = nums.Length - 1;
while (l <= r)
{
int mid = (l + r) / 2;
if (nums[mid] == target)
return mid;
else if (nums[mid] > target)
{
if (nums[mid] >= nums[l])
{
if (nums[l] > target)
l = mid + 1;
else if (nums[l] == target)
return l;
else
r = mid - 1;
}
else
r = mid - 1;
}
else
{
if (nums[mid] <= nums[r])
{
if (nums[r] < target)
r = mid - 1;
else if (nums[r] == target)
return r;
else
l = mid + 1;
}
else
l = mid + 1;
}
}
return -1;
}
}
本文介绍了三个经典的算法问题:合并k个升序链表、删除排序数组中的重复项和搜索旋转排序数组。针对每个问题,提供了详细的思路解析和Java代码实现。合并链表通过迭代方式逐个合并;删除重复项原地修改数组,保持不重复元素;搜索旋转数组运用二分查找法,处理旋转特殊情况。这些算法展示了数据结构和排序技巧在解决复杂问题中的应用。
8万+

被折叠的 条评论
为什么被折叠?



