每日LeetCode力扣(21~25)

Posted 今阳说点啥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每日LeetCode力扣(21~25)相关的知识,希望对你有一定的参考价值。

21. 合并两个有序链表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 
示例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4

  • 解题

fun _0021_mergeTwoLists() 
println("--------_0021_mergeTwoLists-------")
mergeTwoLists(
ListNode(1, ListNode(2, ListNode(4))),
ListNode(1, ListNode(3, ListNode(4)))
)?.print()


/**
* 递归写法,当某个链表为空了,就返回另一个。然后核心还是比较当前两个节点值大小,如果 l1 的小,
* 那么对于 l1 的下一个节点和 l2 调用递归函数,将返回值赋值给 l1.next,然后返回 l1;
* 否则就对于 l2 的下一个节点和 l1 调用递归函数,将返回值赋值给 l2.next,然后返回 l2
*/
fun mergeTwoLists(l1: ListNode?, l2: ListNode?): ListNode?
if (l1 == null) return l2
if (l2 == null) return l1
return if (l1.data < l2.data)
l1.next = mergeTwoLists(l1.next, l2);l1
else
l2.next = mergeTwoLists(l1, l2.next);l2

22. 括号生成

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
示例:
输入:n = 3
输出:[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]

  • 解题

fun _0022_generateParenthesis() 
println("--------_0022_generateParenthesis-------")
println(generateParenthesis(1))
println(generateParenthesis(2))
println(generateParenthesis(3))
println(generateParenthesis(4))


/**
* 思想是找左括号,每找到一个左括号,就在其后面加一个完整的括号,最后再在开头加一个 (),就形成了所有的情况,
* 需要注意的是,有时候会出现重复的情况,所以用set数据结构,好处是如果遇到重复项,不会加入到结果中,
* 最后我们再把set转为vector即可
*/
fun generateParenthesis(n: Int): List<String>
val res = HashSet<String>()
if (n == 0)
res.add("")
else
val pre = generateParenthesis(n - 1)
for (str in pre)
var str = str
for (i in str.indices)
if (str[i] == ()
str = str.substring(0, i + 1) + "()" + str.substring(i + 1, str.length)
res.add(str)
str = str.substring(0, i + 1) + str.substring(i + 3, str.length)


res.add("()$str")


return res.toList()

23. 合并K个升序链表

给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
示例 1:
输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
1->4->5,
1->3->4,
2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6
示例 2:
输入:lists = []
输出:[]
示例 3:
输入:lists = [[]]
输出:[]
提示:
k == lists.length
0 <= k <= 10^4
0 <= lists[i].length <= 500
-10^4 <= lists[i][j] <= 10^4
lists[i] 按 升序 排列
lists[i].length 的总和不超过 10^4

  • 解题

fun _0023_mergeKLists() 
println("--------_0023_mergeKLists-------")
mergeKLists(
arrayOf(
ListNode(1, ListNode(4, ListNode(5))),
ListNode(1, ListNode(3, ListNode(4))),
ListNode(2, ListNode(6)),
)
)?.print()
mergeKLists(arrayOf())?.print()


fun mergeKLists(lists: Array<ListNode?>): ListNode?
val len = lists.size
if (len == 0) return null
else if (len == 1) return lists[0]
var min: ListNode? = null
val prev = ListNode(0)
var head: ListNode? = prev
while (true)
var id = -1
for (i in 0 until len)
if (min == null && lists[i] != null)
min = lists[i]

val curr = lists[i]
if (curr != null && curr.data <= min?.data!!)
min = curr
id = i


if (id != -1)
head?.next = min
head = head?.next
min = null
lists[id] = lists[id]?.next
else break

return prev.next

24. 两两交换链表中的节点

给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例 1:
输入:head = [1,2,3,4]
输出:[2,1,4,3]
示例 2:
输入:head = []
输出:[]
示例 3:
输入:head = [1]
输出:[1]
提示:
链表中节点的数目在范围 [0, 100] 内
0 <= Node.val <= 100

  • 解题

fun _0024_swapPairs() 
println("--------_0024_swapPairs-------")
swapPairs(ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5, ListNode(6)))))))?.print()
swapPairs(ListNode(1, ListNode(2, ListNode(3, ListNode(4)))))?.print()
swapPairs(ListNode(1, ListNode(2, ListNode(3))))?.print()
swapPairs(ListNode(1))?.print()


/**
* 利用了回溯的思想,递归遍历到链表末尾,然后先交换末尾两个,然后依次往前交换:
*/
fun swapPairs(head: ListNode?): ListNode?
if (head?.next == null)
return head

var temp = head.next
head.next = swapPairs(head.next?.next)
temp?.next = head
return temp

25. K 个一组翻转链表

给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例:
给你这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5

说明:
你的算法只能使用常数的额外空间。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

  • 解题

fun _0025_reverseKGroup() 
println("--------_0025_reverseKGroup-------")
reverseKGroup(ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5))))), 2)?.print()
reverseKGroup(ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5))))), 3)?.print()
reverseKGroup(
ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5, ListNode(6)))))),
2
)?.print()
reverseKGroup(
ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5, ListNode(6)))))),
3
)?.print()
reverseKGroup(
ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5, ListNode(6)))))),
4
)?.print()


/**
* 首先遍历整个链表,统计出链表的长度,然后如果长度大于等于k,交换节点,当 k=2 时,每段只需要交换一次,
* 当 k=3 时,每段需要交换2此,所以i从1开始循环,注意交换一段后更新 pre 指针,然后 num 自减k,
* 直到 num<k 时循环结束
*/
fun reverseKGroup(head: ListNode?, k: Int): ListNode?
var dummy = ListNode(-1)
var pre: ListNode? = dummy
var cur: ListNode? = pre
dummy.next = head
var num = 0
while (cur?.next != null)
cur = cur.next
++num

while (num >= k)
cur = pre?.next
for (i in 1 until k)
var temp = cur?.next
cur?.next = temp?.next
temp?.next = pre?.next
pre?.next = temp

pre = cur
num -= k

return dummy.next
我是今阳,如果想要进阶和了解更多的干货,欢迎关注公众号”今阳说“接收我的最新文章


以上是关于每日LeetCode力扣(21~25)的主要内容,如果未能解决你的问题,请参考以下文章

精选力扣500题 第7题 LeetCode 21. 合并两个有序链表c++详细题解

力扣 每日一题 927. 三等分难度:困难

LeetCode21合并两个有序链表

力扣704题 二分查找

LeetCode(力扣)3月「每日 1 题」

LeetCode(力扣)5月「每日 1 题」