终于写出来昨天的LeetCode题了:
看了题解distance实在是太妙了!
C++滑动窗口
解题思路
此处撰写解题思路
代码
class Solution {
public static String minWindow(String s, String t) {
int minL = 0, minR = s.length()+1,l = 0, r = 0, slen = s.length(), tlen = t.length(), distance=0;
Map<Character, Integer> map = new HashMap<>();
Map<Character, Integer> temp = new HashMap<>();
for (int i = 0; i < tlen; i++) {
map.put(t.charAt(i), map.getOrDefault(t.charAt(i), 0)+1);//map保存t中的词频
}
while(r < slen){
while(r<slen&&distance<tlen){
char rc = s.charAt(r++);
if(map.containsKey(rc)){
temp.put(rc, temp.getOrDefault(rc, 0)+1);
if(temp.get(rc)<=map.get(rc)){
distance++;//temp还处于小于等于map中对应的词频就distance加
}
}
}
while(distance==tlen&&l<r){
char lc = s.charAt(l++);
if(temp.containsKey(lc)){
temp.put(lc, temp.get(lc)-1);//当前L走过的字符lc在temp中, temp词频减1
if(temp.get(lc)<map.get(lc)){
if(minR-minL>r-l){//更新子串边界
minR=r;minL=l-1;
}
distance--;//不满足条件,也就说temp对应词频低于map中的词频distance减
}
}
}
}
if(minR>slen||minL<0||tlen>slen){//无解的情况
return "";
}
return s.substring(minL, minR);
}
}
原题如下:
难度困难963收藏分享切换为英文接收动态反馈
给你一个字符串
s
、一个字符串t
。返回s
中涵盖t
所有字符的最小子串。如果s
中不存在涵盖t
所有字符的子串,则返回空字符串""
。注意:如果
s
中存在这样的子串,我们保证它是唯一的答案。
示例 1:
输入:s = "ADOBECODEBANC", t = "ABC" 输出:"BANC"
示例 2:
输入:s = "a", t = "a" 输出:"a"
总结一下
调试花了许多时间,今后注意关注容易出错的点,不要漫无目的调试。
旋转有序数组,特殊二分
原题:
难度中等289收藏分享切换为英文接收动态反馈
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组
[0,0,1,2,2,5,6]
可能变为[2,5,6,0,0,1,2]
)。编写一个函数来判断给定的目标值是否存在于数组中。若存在返回
true
,否则返回false
。示例 1:
输入: nums = [2,5,6,0,0,1,2]
, target = 0 输出: true示例 2:
输入: nums = [2,5,6,0,0,1,2]
, target = 3 输出: false进阶:
- 这是 搜索旋转排序数组 的延伸题目,本题中的
nums
可能包含重复元素。- 这会影响到程序的时间复杂度吗?会有怎样的影响,为什么?
解题思路
此处撰写解题思路
代码
class Solution {
public static boolean search(int []nums, int target) {
int left = 0, right = nums.length-1, len = right+1;
while(left < right){
int med = (left+right)/2;
if(nums[med]==target||nums[left]==target||nums[right]==target) return true;
if(nums[med]==nums[left]&&nums[med]==nums[right]){
left++;right--;//特殊处理
}else if(nums[med] >= nums[left]){//左边严格递增
if(target<nums[med]&&target>=nums[left]){
right = med-1;
}else{
left = med+1;
}
}else{//右边严格递增
if(target>nums[med]&&target<=nums[right]){
left = med+1;
}else{
right = med-1;
}
}
}
if(left>=0&left<len&&nums[left]==target||right<len&&right>=0&&nums[right]==target) return true;
return false;
}
}
删除重复元素,保留不重复元素,11223,只保留3;原题:
给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。
示例 1:
输入: 1->2->3->3->4->4->5 输出: 1->2->5示例 2:
输入: 1->1->1->2->3 输出: 2->3
看了题解,新增一个newHead,其next指向head,val设为head的val,最后返回newHead->next, 非常巧妙
解题思路
此处撰写解题思路
代码
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
ListNode* p = head;
if(p==NULL) return head;
int temp = head->val-1;
ListNode* newHead = new ListNode(temp), *tail = newHead;;
newHead->next = head;
while(p&&p->next){
while(p&&(p->val==temp||p->next&&p->next->val==p->val)){
temp = p->val;
p = p->next;
}
tail->next = p;
if(!p) break;
tail=tail->next;
temp = p->val;
}
return newHead->next;
}
};