目录
16.最接近的三数之和
题目描述
题目分析
和之前做过的那道求三数和最大的思想是一样的,只不过判断条件变一下(我竟然也会应用前面写过的题了,呜呜呜呜我成长了,多亏了写博客这一过程(跪下))
- 先排序(毕竟要和最接近嘛,排完序的数字序列算和方便接近目标值)
- 遍历的过程中,以一个数为固定数,其他俩数由边界向中间跑
代码
int threeSumClosest(vector<int>& nums, int target) {
sort(nums.begin(),nums.end()); //排序
int n=nums.size();
int min=target+99999; //为了使min-target有较大的数值
for(int i=0;i<n;i++){ //i作为固定数的下标
int left=i+1,right=n-1;
while(left<right){
int sum=nums[i]+nums[left]+nums[right];
if(abs(sum-target)<abs(min-target)){ //比较绝对值
min=sum;
}
else{
if(sum-target>0){ //和大了,就让大数减小
right--;
}
else{
left++; //小了就让小数增大
}
}
}
}
return min;
}
17.电话号码的字母组合
题目描述
题目分析
这题是真的折磨
这题最开始自己写没写出来,迷迷瞪瞪的,后来看了题解,可以用队列的方式,看了大概思想后恍然大悟,然后就吭哧吭哧写,然后狠狠改了很久的bug和循环条件,折磨折磨折磨(哭晕)
- 先将第一个数字对应的字母加入队列中
- 之后每次都将原先队列的所有元素出队,进行增加 (增加的是下一个数字对应的字母)
代码
vector<string> arr = { "","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz" };//打表
typedef struct queue { //队列的代码拿的以前写过的改了下
string data;
struct queue* tail;
struct queue* next;
int size; //用于记录当前队列元素数量,使 出队列这一过程 将 原先队列元素 全部出掉
}queue;
queue* QueueCreate() {
queue* obj = new queue;
obj->data = "";
obj->next = obj->tail = NULL;
obj->size = 0;
return obj;
}
void QueuePush(queue* obj, string a) {
queue* newnode = new queue;
newnode->data = a;
newnode->next = NULL;
obj->size++;
if (obj->next == NULL) {
obj->next = obj->tail = newnode;
}
else {
obj->tail->next = newnode;
obj->tail = newnode;
}
}
bool QueueEmpty(queue* obj) {
if (obj->next == NULL) {
return true;
}
return false;
}
string Queuefront(queue* obj) {
return obj->next->data;
}
void QueuePop(queue* obj) {
queue* tmp = obj->next;
if (!QueueEmpty(obj)) {
obj->next = tmp->next;
}
obj->size--;
}
vector<string> letterCombinations(string digits) {
if (digits == "") {
return {};
}
vector<string> ans;
int n = digits.length();
queue* obj=QueueCreate();
//入第一个数字对应的字母
int num = digits[0] - '0';
int size = arr[num].size();
for (int i = 0; i < size; i++) {
string tmp;
tmp += arr[num][i];
QueuePush(obj, tmp);
}
for (int i = 1; i < n; i++) { //数字序列
int num = digits[i] - '0';
int size = arr[num].size(); //记录该数字对应几个字母
int count = obj->size; //记录队列当前元素个数
for (int k = 0; k < count; k++) {
string tmp = Queuefront(obj); //拿到该元素
QueuePop(obj);//出掉
for (int j = 0; j < size; j++) { //字母数
string t = tmp + arr[digits[i] - '0'][j];
QueuePush(obj, t); //处理后再入队,每个元素都要将不同字母都加一遍
}
}
}
while (!QueueEmpty(obj)) {
ans.push_back(Queuefront(obj)); //将队列中的元素加入容器
QueuePop(obj);
}
return ans;
}
387.字符中的第一个唯一字符
题目描述
题目分析
我想的就是遍历字符串,如果出现两次,就赋一个特殊值
因为他要找第一个不重复的字符,所以每次找到该字符后,赋的正常值是递增的,最好就直接对应它的序列
(最开始我直接将字母表顺序最前的返回了,笨死了,没注意是字符串中出现的第一个,不是按字典序)
还有一个绝妙的方法,对字符进行正序查询和逆序查询,如果查到的下标相等,就说明该字符不重复
代码
int firstUniqChar(string s) {
int alphabet[26]={0};
int t;
int count=1;
for(char arr:s){
t=arr-'a';
if(alphabet[t]!=0){
alphabet[t]=99999999;
}
else{
alphabet[t]=count;
}
count++; //作为索引
}
int min=99999999;
for(int i=0;i<26;i++){
if(alphabet[i]<min && alphabet[i]>0){ //找到出现并且只出现一次的值
min=alphabet[i];
}
}
if(min!=99999999){
return min-1;
}else{
return -1;
}
}
int firstUniqChar(string s) {
for(char c:s){
int i=s.find(c),ri=s.rfind(c);
if(i==ri){
return i;
}
}
return -1;
}
先不写leetcode了(跪),赶赶课,想写个聊天室,要学的还有好多,我咋那么没时间(哭死)