LeetCode 142. 环形链表 II
给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。
示例 1:
img
输入:head = [3,2,0,-4], pos = 1输出:返回索引为 1 的链表节点解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
img
输入:head = [1,2], pos = 0输出:返回索引为 0 的链表节点解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
img
输入:head = [1], pos = -1输出:返回 null解释:链表中没有环。
提示:
链表中节点的数目范围在范围 [0, 104] 内
-105 <= Node.val <= 105
pos 的值为 -1 或者链表中的 ...
LeetCode 82. 删除排序链表中的重复元素 II
给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。
示例 1:
img
输入:head = [1,2,3,3,4,4,5]输出:[1,2,5]
示例 2:
img
输入:head = [1,1,1,2,3]输出:[2,3]
提示:
链表中节点数目在范围 [0, 300] 内
-100 <= Node.val <= 100
题目数据保证链表已经按升序 排列
思路
使用dummy保存头结点,prev和curr进行移动,每当发现curr后面的值重复时,则将curr移动到下一个不重复的节点,然后将prev的next指向curr即可。
class Solution { public ListNode deleteDuplicates(ListNode head) { ListNode dummy = new ListNode(0); dummy.next = head; ListNode prev = dummy, curr = head; w ...
LeetCode 98. 验证二叉搜索树
给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。
有效 二叉搜索树定义如下:
节点的左子树只包含 小于 当前节点的数。
节点的右子树只包含 大于 当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
示例 1:
img
输入:root = [2,1,3]输出:true
示例 2:
img
输入:root = [5,1,4,null,null,3,6]输出:false解释:根节点的值是 5 ,但是右子节点的值是 4 。
提示:
树中节点数目范围在[1, 104] 内
-231 <= Node.val <= 231 - 1
思路
一棵树是二叉搜索树当且仅当它的左孩子和右孩子是二叉搜索树,且当前节点的值在范围内。故得出递归算法如下。
class Solution { public boolean isValidBST(TreeNode root) { return isValidBST(root, Long.MIN_VALUE, Long.MAX_VALUE); } public boolean ...
LeetCode 1401. 圆和矩形是否有重叠
给你一个以 (radius, x_center, y_center) 表示的圆和一个与坐标轴平行的矩形 (x1, y1, x2, y2),其中 (x1, y1) 是矩形左下角的坐标,(x2, y2) 是右上角的坐标。
如果圆和矩形有重叠的部分,请你返回 True ,否则返回 False 。
换句话说,请你检测是否 存在 点 (xi, yi) ,它既在圆上也在矩形上(两者都包括点落在边界上的情况)。
示例 1:
img
输入:radius = 1, x_center = 0, y_center = 0, x1 = 1, y1 = -1, x2 = 3, y2 = 1输出:true解释:圆和矩形有公共点 (1,0)
示例 2:
输入:radius = 1, x_center = 0, y_center = 0, x1 = -1, y1 = 0, x2 = 0, y2 = 1输出:true
示例 3:
输入:radius = 1, x_center = 1, y_center = 1, x1 = -3, y1 = -3, x2 = 3, y2 = 3输出:true
示例 4:
输 ...
LeetCode 232. 用栈实现队列
本题是一道简单题,饶有趣味的是,本题的解法是分摊复杂度的一种典型应用。
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
说明:
你 只能 使用标准的栈操作 —— 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
示例 1:
输入:["MyQueue", "push", "push", "peek", "pop", "empty"][[], [1], [2], [], [], []]输出:[null, null, null, 1, 1, false]解释:My ...
LeetCode 5. 最长回文子串
给你一个字符串 s,找到 s 中最长的回文子串。
示例 1:
输入:s = "babad"输出:"bab"解释:"aba" 同样是符合题意的答案。
示例 2:
输入:s = "cbbd"输出:"bb"
提示:
1 <= s.length <= 1000
s 仅由数字和英文字母组成
思路
不难发现,当到构成一个回文子串时,到一定也构成一个回文子串。若表示到的子串长度,那么状态转移方程为: 但是本题并不需要求最长的子串长,而是求下标。所以我们让dp[i][j]表示i和j之间是否构成回文子串。
class Solution { public String longestPalindrome(String s) { int len = s.length(); if (len < 2) return s; int max = 0; int x = 0, y = 0; // dp[i][j]表示从s[i]到s[j]是不是一个回文字符串 boolean[][] dp = new boo ...
LeetCode 200. 岛屿数量
给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。
示例 1:
输入:grid = [ ["1","1","1","1","0"], ["1","1","0","1","0"], ["1","1","0","0","0"], ["0","0","0","0","0"]]输出:1
示例 2:
输入:grid = [ ["1","1","0","0","0"], ["1","1","0","0","0"], ["0","0","1","0","0"], ["0","0","0","1","1"]]输出:3
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 300
grid[i][j] 的值为 '0' 或 '1'
思路
dfs搜索,每次遇到一个岛屿则将陆地全部变成海水,记录遇到的岛屿数即可。
class Solution { publi ...
LeetCode 33. 搜索旋转排序数组
整数数组 nums 按升序排列,数组中的值 互不相同 。
在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。
给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。
示例 1:
输入:nums = [4,5,6,7,0,1,2], target = 0输出:4
示例 2:
输入:nums = [4,5,6,7,0,1,2], target = 3输出:-1
示例 3:
输入:nums = [1], target = 0输出:-1
提示:
1 <= nums.length <= 5000
-10^4 <= nums[i] ...
LeetCode 25. K个一组翻转链表
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
进阶:
你可以设计一个只使用常数额外空间的算法来解决此问题吗?
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
示例 1:
img
输入:head = [1,2,3,4,5], k = 2输出:[2,1,4,3,5]
示例 2:
img
输入:head = [1,2,3,4,5], k = 3输出:[3,2,1,4,5]
示例 3:
输入:head = [1,2,3,4,5], k = 1输出:[1,2,3,4,5]
示例 4:
输入:head = [1], k = 1输出:[1]
提示:
列表中节点的数量在范围 sz 内
1 <= sz <= 5000
0 <= Node.val <= 1000
1 <= k <= sz
思路
只需先计算出链表总长度,然后以k个为一组迭代即可 ,翻转的思路参照剑指 Offer 24. 反转链表。
cla ...
剑指Offer 24. 反转链表
本题是一道简单题,解析本题的原因是本题的思想可以用于解决25. K 个一组翻转链表这道Hard题。
先看题目描述。定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例:
输入: 1->2->3->4->5->NULL输出: 5->4->3->2->1->NULL
限制:
0 <= 节点个数 <= 5000
注意:本题与主站 206 题相同:https://leetcode-cn.com/problems/reverse-linked-list/
思路
比较容易想到的思路是双指针迭代,如同官方解析所说的:
假设链表为,我们想要把它改成。
在遍历链表时,将当前节点的指针改为指向前一个节点。由于节点没有引用其前一个节点,因此必须事先存储其前一个节点。在更改引用之前,还需要存储后一个节点。最后返回新的头引用。
class Solution { public ListNode reverseList(ListNode head) { ListNode prev = null; ...