# 算法学习——LeetCode力扣补充篇15
560. 和为 K 的子数组
描述
给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。
子数组是数组中元素的连续非空序列。
示例
示例 1:
输入:nums = [1,1,1], k = 2
输出:2
示例 2:
输入:nums = [1,2,3], k = 3
输出:2
提示
1 <= nums.length <= 2 * 104
-1000 <= nums[i] <= 1000
-107 <= k <= 107
代码解析
暴力超时
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
int result = 0;
int sum = 0;
for(int i=0 ; i<nums.size() ; i++)
{
for(int j=i ; j<nums.size() ; j++)
{
sum += nums[j];
if(sum == k) result++;
}
sum = 0;
}
return result;
}
};
前缀和 + map
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
int result = 0;
int pre = 0;
unordered_map<int , int> preMap;
preMap[pre]++;
for(int i=0 ; i<nums.size() ; i++)
{
pre += nums[i];
if(preMap.find( pre -k ) != preMap.end() )
result += preMap[pre-k];
preMap[pre]++;
}
return result;
}
};
468. 验证IP地址
描述
给定一个字符串 queryIP。如果是有效的 IPv4 地址,返回 “IPv4” ;如果是有效的 IPv6 地址,返回 “IPv6” ;如果不是上述类型的 IP 地址,返回 “Neither” 。
有效的IPv4地址 是 “x1.x2.x3.x4” 形式的IP地址。 其中 0 <= xi <= 255 且 xi 不能包含 前导零。例如: “192.168.1.1” 、 “192.168.1.0” 为有效IPv4地址, “192.168.01.1” 为无效IPv4地址; “192.168.1.00” 、 “192.168@1.1” 为无效IPv4地址。
一个有效的IPv6地址 是一个格式为“x1:x2:x3:x4:x5:x6:x7:x8” 的IP地址,其中:
1 <= xi.length <= 4
xi 是一个 十六进制字符串 ,可以包含数字、小写英文字母( ‘a’ 到 ‘f’ )和大写英文字母( ‘A’ 到 ‘F’ )。
在 xi 中允许前导零。
例如 “2001:0db8:85a3:0000:0000:8a2e:0370:7334” 和 “2001:db8:85a3:0:0:8A2E:0370:7334” 是有效的 IPv6 地址,而 “2001:0db8:85a3::8A2E:037j:7334” 和 “02001:0db8:85a3:0000:0000:8a2e:0370:7334” 是无效的 IPv6 地址。
示例
示例 1:
输入:queryIP = “172.16.254.1”
输出:“IPv4”
解释:有效的 IPv4 地址,返回 “IPv4”
示例 2:
输入:queryIP = “2001:0db8:85a3:0:0:8A2E:0370:7334”
输出:“IPv6”
解释:有效的 IPv6 地址,返回 “IPv6”
示例 3:
输入:queryIP = “256.256.256.256”
输出:“Neither”
解释:既不是 IPv4 地址,又不是 IPv6 地址
提示
queryIP 仅由英文字母,数字,字符 ‘.’ 和 ‘:’ 组成。
代码解析
class Solution {
public:
bool cheakIP4(vector<string> &tmpIP4)
{
if(tmpIP4.size() != 4) return false;
int tmp = 0;
for(int i=0 ; i<tmpIP4.size() ; i++)
{
if(tmpIP4[i].size() > 1 && tmpIP4[i][0] == '0') return false;
if(tmpIP4[i].size() == 0 || tmpIP4[i].size() > 3 ) return false;
for(int j=0 ; j<tmpIP4[i].size() ; j++)
{
if( tmpIP4[i][j] >= '0' &&tmpIP4[i][j] <= '9') {}
else return false;
}
tmp = stoi(tmpIP4[i]);
if(tmp < 0 || tmp > 255) return false;
}
return true;
}
bool cheakIP6(vector<string> &tmpIP6)
{
if(tmpIP6.size() != 8) return false;
int tmp = 0;
for(int i=0 ; i<tmpIP6.size() ; i++)
{
if(tmpIP6[i].size() == 0 || tmpIP6[i].size() > 4) return false;
for(int j=0 ; j<tmpIP6[i].size() ; j++)
{
if( (tmpIP6[i][j] >= '0' &&tmpIP6[i][j] <= '9')
|| (tmpIP6[i][j] >= 'a' &&tmpIP6[i][j] <= 'f')
|| (tmpIP6[i][j] >= 'A' &&tmpIP6[i][j] <= 'F'))
{}
else return false;
}
}
return true;
}
string validIPAddress(string queryIP) {
string tmp;
vector<string> tmpIP4;
vector<string> tmpIP6;
if(queryIP.find('.') != -1 )
{
for(int i=0 ; i <queryIP.size() ; i++)
{
if(queryIP[i] == '.')
{
tmpIP4.push_back(tmp);
tmp.clear();
continue;
}
tmp += queryIP[i];
}
tmpIP4.push_back(tmp);
if(cheakIP4(tmpIP4) == true) return "IPv4";
else return "Neither";
}
else if(queryIP.find(':') != -1 )
{
for(int i=0 ; i <queryIP.size() ; i++)
{
if(queryIP[i] == ':')
{
tmpIP6.push_back(tmp);
tmp.clear();
continue;
}
tmp += queryIP[i];
}
tmpIP6.push_back(tmp);
if(cheakIP6(tmpIP6) == true) return "IPv6";
else return "Neither";
return "IPv6";
}
return "Neither";
}
};
138. 随机链表的复制
描述
给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。
构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。
例如,如果原链表中有 X 和 Y 两个节点,其中 X.random --> Y 。那么在复制链表中对应的两个节点 x 和 y ,同样有 x.random --> y 。
返回复制链表的头节点。
用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:
val:一个表示 Node.val 的整数。
random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为 null 。
你的代码 只 接受原链表的头节点 head 作为传入参数。
示例
示例 1:
输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
示例 2:
输入:head = [[1,1],[2,1]]
输出:[[1,1],[2,1]]
示例 3:
输入:head = [[3,null],[3,0],[3,null]]
输出:[[3,null],[3,0],[3,null]]
提示
0 <= n <= 1000
-104 <= Node.val <= 104
Node.random 为 null 或指向链表中的节点。
代码解析
复制带随机指针的链表
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
public:
map<Node* , Node*> myMap;
Node* trak_back(Node* cur)
{
if(cur == nullptr ) return nullptr;
if( myMap.find(cur) == myMap.end() )
{
Node* tmp = new Node(cur->val);
myMap[cur] = tmp;
tmp->next = trak_back(cur->next);
tmp->random = trak_back(cur->random);
}
return myMap[cur];
}
Node* copyRandomList(Node* head) {
return trak_back(head);
}
};