- 无重复字符的最长子串
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串
代码:
class Solution {
public int lengthOfLongestSubstring(String s) {
if(s.length() == 0){
return 0;
}
//用于计数
int count = 0;
int max = -1;
//将字符串储存成字符数组
char[] strs = s.toCharArray();
//定义一个集合存储不重复的字符
List<Character> str_list = new ArrayList<>();
//跟python的for i in list是一个用法
for(char c: strs){
//当遇上重复的字符时
if(str_list.contains(c)){
//如果之前的计数大于max,则对max重新赋值
if(count > max){
max = count;
}
//遇上重复字符,就要对集合里面的字符进行清空,与从同时每删一个计数减一
while(str_list.contains(c)){
count--;
System.out.println(str_list.get(0));
str_list.remove(0);
System.out.println("---");
}
}
str_list.add(c);
count++;
}
if(count >= max){
max = count;
}
return max;
}
}
- 最接近的三数之和
对于这道题采用的是一层循环+双指针的方式解题
class Solution {
public int threeSumClosest(int[] nums, int target) {
int i, j, k;
//定义最接近target的数
int closet=nums[0] + nums[1] + nums[2];
//对传进来的数组进行排序
Arrays.sort(nums);
for(i=0; i<nums.length-2; i++){
j = i + 1;
k = nums.length - 1;
//双指针,一个指向头,一个指向尾
while(k > j){
int num = nums[j] + nums[i] + nums[k];
//当前三数与target的差的绝对值比上一次的差小的话,对最接近的数重新赋值
if(Math.abs(num - target) < Math.abs(closet-target)){
closet = num;
}
//因为nums是有序数组,通过判断num与target的关系来确定两个指针的走向
if(num > target){
k--;
}else if(num < target){
j++;
}else{
//num与target相等即返回target
return target;
}
}
}
return closet;
}
}
- 二叉树的最大深度
用递归解,终止条件是节点为空,返回给上一级的是当前节点的个数,为空返回0,不为空返回1,因此这里需要用 maxDepth(root.left)+1 来返回给上一级。
class Solution {
public int maxDepth(TreeNode root) {
if(root == null){
return 0;
}
return Math.max(maxDepth(root.left)+1,maxDepth(root.right)+1);
}
}
在评论区找到了另一种解法 栈解法
栈解法:深度优先搜索,栈的最大长度就是树的最大深度
var maxDepth = function(root) {
if(root === null) return 0;
let depth = 1;
let stack = [root];
let currentNode = root;
while(stack.length) {
while(getNotArrivedChild(currentNode)) {
stack.push(getNotArrivedChild(currentNode));
currentNode = getNotArrivedChild(currentNode);
//这里给访问过的节点标记一下
currentNode.ok = true;
//如果加入这个节点后,stack长度大于当前depth,就更新depth为stack长度。
if(stack.length > depth) depth = stack.length;
}
stack.pop();
currentNode = stack[stack.length-1];
}
return depth;
};
//这个函数用来返回当前节点还未被访问过的子节点
function getNotArrivedChild(root) {
if(root.left && !root.left.ok) return root.left;
if(root.right && !root.right.ok) return root.right;
return null;
}
再记录一下栈解法用c实现的,方便复习:
#define N (100)
// 记录每个节点和对应的高度
struct stack{
struct TreeNode* node;
int depth;
}stack[N];
// 桟指针和树最大高度
int i = 0;
int depth = 0;
int maxDepth(struct TreeNode* root) {
if(root == NULL) return 0;
stack[i].node = root;
stack[i].depth = depth = 1;
i++;
while(i>0) // 桟不空
{
// 出栈
--i;
// 保存出栈的节点和高度
struct TreeNode* t = stack[i].node;
int curDepth = stack[i].depth;
// 更新最大高度
depth = depth > curDepth ? depth : curDepth;
if(t->left != NULL) // 不为空则入栈
{
stack[i].node = t->left;
stack[i].depth = curDepth + 1;
++i;
}
if(t->right != NULL) // 不为空则入栈
{
stack[i].node = t->right;
stack[i].depth = curDepth + 1;
++i;
}
}
return depth;
}