88. 合并两个有序数组
给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。
说明:
初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例:
输入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3
输出: [1,2,2,3,5,6]
直接插入
从nums1中倒序找到nums2[i]的插入位置,然后插入,遍历所有nums2[i],即合并成功。
因为两个数组都是递增的,倒序找更快。不要小看这种方法,也是非常快的,而且空间复杂度为O(1).
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
int i = 0, j = m - 1;
int n1 = j;
while(i < n)
{
while(j >= 0) if(nums1[j] > nums2[i]) j--; else break;
for(int k = n1; k >= j+1; k--)
{
nums1[k+1] = nums1[k];
}
nums1[j+1] = nums2[i];
n1++;
i++;
j = n1;
}
}
};
双指针
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
int p1 = m - 1, p2 = n - 1, p = m + n -1;
while(p1 >= 0 && p2 >= 0)
{
nums1[p--] = (nums1[p1] < nums2[p2]) ? nums2[p2--] : nums1[p1--];
}
// nums2可能有剩余,将剩余的添加到nums1中。
for(int i = 0; i <= p2; i++)
nums1[i] = nums2[i];
}
};
从提交结果来看,第二种方法比第一种方法慢一点。
141. 环形链表
给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。
双指针
一快一慢指针,在有环的情况下,快指针会追上慢指针,反之无环。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool hasCycle(ListNode *head) {
if(head == NULL)
return false;
ListNode *p = head, *q = head;
int flag = false;
while(p->next != NULL && q->next != NULL)
{
p = p->next;
if(q->next->next != NULL)
q = q->next->next;
else
break;
if(p == q)
{
flag = true;
break;
}
}
return flag;
}
};
524. 通过删除字母匹配到字典里最长单词
给定一个字符串和一个字符串字典,找到字典里面最长的字符串,该字符串可以通过删除给定字符串的某些字符来得到。如果答案不止一个,返回长度最长且字典顺序最小的字符串。如果答案不存在,则返回空字符串。
示例 1:
输入:
s = “abpcplea”, d = [“ale”,“apple”,“monkey”,“plea”]
输出:
“apple”
示例 2:
输入:
s = “abpcplea”, d = [“a”,“b”,“c”]
输出:
“a”
说明:
所有输入的字符串只包含小写字母。
字典的大小不会超过 1000。
所有输入的字符串长度不会超过 1000。
暴力匹配1
先对d按首字母大小排序,然后直接匹配,找到匹配成功字符串最长的那个。
class Solution {
public:
string findLongestWord(string s, vector<string>& d) {
sort(d.begin(), d.end());
int max = 0, ans = -1, i = 0;
for(i = 0; i < d.size(); ++i)
{
int j = 0, n = d[i].length(), k = 0, flag = 0;
while(j < s.length() && k < n)
{
if(s[j] == d[i][k])
j++, k++;
else
j++;
if(k == n)
flag = 1;
}
if(flag && max < n)
max = n, ans = i;
}
return ans != -1 ? d[ans] : "";
}
};
暴力匹配2
不用排序,每次记录匹配成功的字符串,跟下一次比较取最长且首字母最小的那个。
class Solution {
public:
bool is_seq(string a, string b) // 判断b是不是a的字符串
{
int j = 0;
for(int i = 0; i < a.length() && j < b.length(); ++i)
if(a[i] == b[j])
j++;
return j == b.length();
}
string findLongestWord(string s, vector<string>& d) {
string max = "";
for(string s1 : d)
if(is_seq(s, s1) && (max.length() < s1.length() || (max.length() == s1.length() && max > s1)))
max = s1;
return max;
}
};