目录
第一题---返回最大差值(258)
给你一个下标从 0 开始的整数数组 nums ,该数组的大小为 n ,请你计算 nums[j] - nums[i] 能求得的 最大差值 ,其中 0 <= i < j < n 且 nums[i] < nums[j] 。
返回 最大差值 。如果不存在满足要求的 i 和 j ,返回 -1 。
vector<int>& nums------vector指代的是一维数组
-
vector<int> nums;//不指定长度
-
vector<int> nums(n); // 指定长度为
添加元素:nums.push_back(1);//直接从数组末端添加
删除元素
-
nums.resize(nums.size-i); //直接将数组长度减小,某种方式上删掉了后面i个
-
nums.pop_back();//删掉最后一个元素
其他
获得长度:nums.size()
排序(O(nlogn)):sort(nums.begin(),nums.end());
翻转:reverse(nums.begin(), nums.end());
合并两个vector:合并nums1和nums2,并将合并后的数组赋值给nums
class Solution {
public:
int maximumDifference(vector<int>& nums) {
//设置一个vector的一维数组,取名为nums
int n = nums.size();//定义初始化数组的长度
int ans = -1, premin = nums[0];//设置一个最小值,以及最小的差值是多少
for (int i = 1; i < n; ++i) {//从下一位开始进行遍历
if (nums[i] > premin) {//数组中的下一位值大于最小值的时候
ans = max(ans, nums[i] - premin);//比较这个值与最小值的差值比较,并且是否更新
} else {
premin = nums[i];//如果下一位的值比最小值要小的话,更新最小值
}
}
return ans;
}
};
第二题----俩数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
(1)第一种思路就是比较简单,俩层遍历直接找到最先找到的
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
int n=nums.size();
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(target==nums[i]+nums[j]){
return {i,j};
}
}
}
return {};
}
};
(2)
注意到方法一的时间复杂度较高的原因是寻找 target - x 的时间复杂度过高。因此,我们需要一种更优秀的方法,能够快速寻找数组中是否存在目标元素。如果存在,我们需要找出它的索引。
使用哈希表,可以将寻找 target - x 的时间复杂度降低到从 O(N)O(N) 降低到 O(1)O(1)。
这样我们创建一个哈希表,对于每一个 x,我们首先查询哈希表中是否存在 target - x,然后将 x 插入到哈希表中,即可保证不会让 x 和自己匹配。
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
unordered_map<int, int> hashtable;// unordered_map ---map容器为无序定义
for (int i = 0; i < nums.size(); ++i) {
auto it = hashtable.find(target - nums[i]);//auto---类似于一个推到的作用,自动判别出是什么样的类型,并且返回的是一个迭代器的类型
//当开始的时候,寻找map容器中的对应关系,并没有合适的对应关系,此时find返回的是容器的最后一位,并且执行相应的后续位置,if跳过,并且在map中添加对应的键值对
if (it != hashtable.end()) {it跟最后一个不一样的时候
return {it->second, i};//返回他的值
}
hashtable[nums[i]] = i;//讲map中的值转向下一项
}
return {};
}
};
第三题---俩数相加
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode * header=nullptr,*p_ptr=nullptr;
int carry=0;
while(l1||l2){
int n1=l1?l1->val:0;
int n2=l2?l2->val:0;
int sum=n1+n2+carry;
if(!header){
p_ptr=header=new ListNode(sum%10);
}else{
p_ptr->next= new ListNode(sum%10);
p_ptr=p_ptr->next;
}
carry=sum/10;
if(l1){
l1=l1->next;
}
if(l2){
l2=l2->next;
}
}
if(carry!=0){
p_ptr->next= new ListNode(carry);
}
return header;
}
};
第四题----无重复字符的最长字串
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
不断地刷新i的位置,当rk在occ当中找不到对应的值时候,不断的增加,直到找到一个一样的为止。
对于i来说,他是不断增加的,就导致一直在向右移,当rk储存一组完全不一样的字符串的时候,i会不断略过,并且清楚rk中储存的字符串,相当于一种窗口移动,使i指向rk中字符串遇到的第一个相同的,作为一个新的起始位置,之后在移动rk的位置,在继续寻找差值最大的那一组字符串
class Solution {
public:
int lengthOfLongestSubstring(string s) {
// 哈希集合,记录每个字符是否出现过
unordered_set<char> occ;
int n = s.size();
// 右指针,初始值为 -1,相当于我们在字符串的左边界的左侧,还没有开始移动
int rk = -1, ans = 0;
// 枚举左指针的位置,初始值隐性地表示为 -1
for (int i = 0; i < n; ++i) {
if (i != 0) {
// 左指针向右移动一格,移除一个字符
occ.erase(s[i - 1]);
}
while (rk + 1 < n && !occ.count(s[rk + 1])) {
// 不断地移动右指针
occ.insert(s[rk + 1]);
++rk;
}
// 第 i 到 rk 个字符是一个极长的无重复字符子串
ans = max(ans, rk - i + 1);
}
return ans;
}
};
第五题-----最长回文字串
给你一个字符串 s
,找到 s
中最长的回文子串。
在这里主要是用的寻找一个中间数的方法,找到一个数不断向外扩张
首先的是选用一个数的进行扩张,找到的都是类似于ada,a这种奇数字节的
然后再用偶数字节进行扩张去寻找,aa,adda这种类型的,进行比较,然后放入设定的start以及end中进行保存,并且不断循环判断,更新start,end的值,并且返回,利用字符串的substr进行字符串中的截取
class Solution {
public:
pair<int, int> expandAroundCenter(const string& s, int left, int right) {
while (left >= 0 && right < s.size() && s[left] == s[right]) {
--left;
++right;
}
return {left + 1, right - 1};
}
string longestPalindrome(string s) {
int start = 0, end = 0;
for (int i = 0; i < s.size(); ++i) {
auto [left1, right1] = expandAroundCenter(s, i, i);
auto [left2, right2] = expandAroundCenter(s, i, i + 1);
if (right1 - left1 > end - start) {
start = left1;
end = right1;
}
if (right2 - left2 > end - start) {
start = left2;
end = right2;
}
}
return s.substr(start, end - start + 1);
}
};
第六题-z型变换
、将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 “LEETCODEISHIRING” 行数为 3 时,排列如下:
L C I R
E T O E S I I G
E D H N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“LCIRETOESIIGEDHN”。
请你实现这个将字符串进行指定行数变换的函数:
思路:::_____________________________________
做完看了下其他人的答案,感觉大部分人都把这道题搞得有点复杂了。
这道题可以这么考虑:对于输入的字符串s,其下标 i / (numRows-1) 如果为偶数或零,则代表该下标代表的字符在Z字型中属于竖列。如果 i / (numRows-1) 如果为奇数,则代表该下标代表的字符在Z字型中属于斜列(Z字型的中间倾斜部分)。
如果当前字符属于竖列,则按照正序依次保存在字符串数组 temp 中(temp[remain].push_back(s[i])),如果属于斜列,则逆序保存(temp[numRows-remain-1].push_back(s[i]))。
最后将 temp 数组依次按序输出就是最终答案。
class Solution {
public:
string convert(string s, int numRows) {
vector<string> temp(numRows);
string res;
if(s.empty() || numRows < 1) return res;
if(numRows == 1) return s;
for(int i = 0; i < s.size(); i++){
int ans = i / (numRows-1);
int remain = i % (numRows-1);
if(ans % 2 == 0){ //结果为偶数或0
temp[remain].push_back(s[i]); //按余数正序保存
}
if(ans % 2 != 0){ //结果为奇数
temp[numRows-remain-1].push_back(s[i]); //按余数倒序保存
}
}
for(int i = 0; i < temp.size(); i++){
res += temp[i];
}
return res;
}
};
第七题:整数反转
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−, − 1] ,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)<