C/C++每日一练(20230514) 全排列、分数转小数、排序链表去重II

简介: C/C++每日一练(20230514) 全排列、分数转小数、排序链表去重II

1. 全排列


给定一个 没有重复 数字的序列,返回其所有可能的全排列。


示例:


输入: [1,2,3]

输出: [[1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1]]

以下程序实现了这一功能,请你填补空白处内容:

···

#include <bits/stdc++.h>
using namespace std;
class Solution
{
public:
    vector<vector<int>> permute(vector<int> &nums)
    {
        vector<vector<int>> res;
        vector<bool> used(nums.size());
        dfs(nums, used, res);
        return res;
    }
private:
    vector<int> stack;
    void dfs(vector<int> &nums, vector<bool> &used, vector<vector<int>> &res)
    {
        if (stack.size() == nums.size())
        {
            res.push_back(stack);
        }
        else
        {
            for (int i = 0; i < nums.size(); i++)
            {
                if (!used[i])
                {
                    _______________;
                }
            }
        }
    }
};
···


出处:

https://edu.csdn.net/practice/27810770

代码:

#include <bits/stdc++.h>
using namespace std;
class Solution
{
public:
    vector<vector<int>> permute(vector<int> &nums)
    {
        vector<vector<int>> res;
        vector<bool> used(nums.size());
        dfs(nums, used, res);
        return res;
    }
private:
    vector<int> stack;
    void dfs(vector<int> &nums, vector<bool> &used, vector<vector<int>> &res)
    {
        if (stack.size() == nums.size())
        {
            res.push_back(stack);
        }
        else
        {
            for (int i = 0; i < nums.size(); i++)
            {
                if (!used[i])
                {
                    used[i] = true;
                    stack.push_back(nums[i]);
                    dfs(nums, used, res);
                    stack.pop_back();
                    used[i] = false;
                }
            }
        }
    }
};
string Vector2dToString(vector<vector<int>> vec2d, string sep = ",")
{
    stringstream ss;
    ss << "[";
    for (int i = 0; i < vec2d.size(); ++i) {
        ss << "[";
        copy(vec2d[i].begin(), vec2d[i].end(), ostream_iterator<int>(ss, sep.c_str()));
    ss.seekp(-(int)sep.size(), ios_base::end);
        ss << "]" << sep;
    }
    ss.seekp(-(int)sep.size(), ios_base::end);
    ss << "]";
    return ss.str();
}
int main()
{
  Solution s;
  vector<int> nums = {1,2,3};
  cout << Vector2dToString(s.permute(nums)) << endl;
  return 0;
} 

输出:

[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]


2. 分数到小数


给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以 字符串形式返回小数 。

如果小数部分为循环小数,则将循环的部分括在括号内。


如果存在多个答案,只需返回 任意一个 。


对于所有给定的输入,保证 答案字符串的长度小于 104 。


示例 1:

输入:numerator = 1, denominator = 2

输出:"0.5"


示例 2:

输入:numerator = 2, denominator = 1

输出:"2"


示例 3:

输入:numerator = 2, denominator = 3

输出:"0.(6)"


示例 4:

输入:numerator = 4, denominator = 333

输出:"0.(012)"


示例 5:

输入:numerator = 1, denominator = 5

输出:"0.2"


提示:

   -2^31 <= numerator, denominator <= 2^31 - 1

   denominator != 0


出处:

https://edu.csdn.net/practice/27810771

代码:

#include <bits/stdc++.h>
using namespace std;
class Solution
{
public:
    string fractionToDecimal(int numerator, int denominator)
    {
        if (denominator == 0)
            return "";
        string ans;
        if ((numerator > 0 && denominator < 0) || (numerator < 0 && denominator > 0))
            ans = "-";
        long long num = abs(static_cast<long long>(numerator));
        long long den = abs(static_cast<long long>(denominator));
        long long quo = num / den;
        long long rem = num % den;
        ans = ans + to_string(quo);
        if (!rem)
            return ans;
        ans += ".";
        unordered_map<long long, int> u_m;
        string s = "";
        int pos = 0;
        while (rem)
        {
            if (u_m.find(rem) != u_m.end())
            {
                s.insert(u_m[rem], "(");
                s += ")";
                return ans + s;
            }
            u_m[rem] = pos++;
            s += to_string((rem * 10) / den);
            rem = (rem * 10) % den;
        }
        return ans + s;
    }
};
int main()
{
  Solution s;
  cout << s.fractionToDecimal(1, 2) << endl;
  cout << s.fractionToDecimal(2, 1) << endl;
  cout << s.fractionToDecimal(2, 3) << endl;
  cout << s.fractionToDecimal(4, 333) << endl;
  cout << s.fractionToDecimal(1, 5) << endl;
  return 0;
} 

输出:

0.5

2

0.(6)

0.(012)

0.2


3. 删除排序链表中的重复元素 II (C语言)


存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除链表中所有存在数字重复情况的节点,只保留原始链表中 没有重复出现 的数字。


返回同样按升序排列的结果链表。


示例 1:

5b9243e41528c71944e0f9436d8c249f.jpeg

输入:head = [1,2,3,3,4,4,5]

输出:[1,2,5]


示例 2:

f43c3f1fdb51738ae73ac8543c9b4e9b.jpeg

输入:head = [1,1,1,2,3]

输出:[2,3]


提示:

   链表中节点数目在范围 [0, 300] 内

   -100 <= Node.val <= 100

   题目数据保证链表已经按升序排列

以下程序实现了这一功能,请你填补空白处内容:


#include <stdio.h>#include <stdlib.h>structListNode{
intval;
structListNode*next;
};
structListNode*deleteDuplicates(structListNode*head)
{
structListNodedummy;
structListNode*p, *q, *prev;
prev=&dummy;
dummy.next=head;
p=q=head;
while (p!=NULL)
    {
_____________________;
    }
returndummy.next;
}
intmain(intargc, char**argv)
{
inti;
structListNode*head=NULL;
structListNode*prev=NULL;
structListNode*p;
for (i=0; i<argc-1; i++)
    {
p=malloc(sizeof(*p));
p->val=atoi(argv[i+1]);
p->next=NULL;
if (head==NULL)
        {
head=p;
prev=head;
        }
else        {
prev->next=p;
prev=p;
        }
    }
p=deleteDuplicates(head);
while (p!=NULL)
    {
printf("%d ", p->val);
p=p->next;
    }
printf("\n");
return0;
}
```


出处:

https://edu.csdn.net/practice/27810772

代码: (C语言)

#include <stdio.h>#include <stdlib.h>structListNode{
intval;
structListNode*next;
};
structListNode*deleteDuplicates(structListNode*head)
{
structListNodedummy;
structListNode*p, *q, *prev;
prev=&dummy;
dummy.next=head;
p=q=head;
while (p!=NULL)
    {
while (q!=NULL&&q->val==p->val)
        {
q=q->next;
        }
if (p->next==q)
        {
prev=p;
        }
else        {
prev->next=q;
        }
p=q;
    }
returndummy.next;
}
intmain()
{
inti;
structListNode*head=NULL;
structListNode*prev=NULL;
structListNode*p;
intnums[] = {1,2,3,3,4,4,5};
intcount=sizeof(nums) /sizeof(nums[0]);
for (i=0; i<count; i++)
    {
p= (ListNode*)malloc(sizeof(*p));
p->val=nums[i];
p->next=NULL;
if (head==NULL)
        {
head=p;
prev=head;
        }
else        {
prev->next=p;
prev=p;
        }
    }
p=deleteDuplicates(head);
while (p!=NULL)
    {
printf("%d->", p->val);
p=p->next;
    }
printf("null\n");
return0;
}


输出:

1->2->5->null

单链表的创建、打印写成函数形式:

#include <stdio.h>
#include <stdlib.h>
#define Test(nums) {\
    count = sizeof(nums) / sizeof(nums[0]);\
    head = arrayToList(nums, count);\
    printList(head);\
      head = deleteDuplicates(head);\
    printList(head);}
struct ListNode
{
    int val;
    struct ListNode *next;
};
struct ListNode *deleteDuplicates(struct ListNode *head)
{
    struct ListNode dummy;
    struct ListNode *p, *q, *prev;
    prev = &dummy;
    dummy.next = head;
    p = q = head;
    while (p != NULL)
    {
        while (q != NULL && q->val == p->val)
    {
        q = q->next;
    }
    if (p->next == q)
    {
        prev = p;
    }
    else
    {
        prev->next = q;
    }
    p = q;
    }
    return dummy.next;
}
struct ListNode *arrayToList(int* nums, int count)
{
    struct ListNode *head = NULL;
    struct ListNode *prev = NULL;
    struct ListNode *p;
    if (count == 0) return NULL;
    for (int i = 0; i < count; i++)
    {
        p = (ListNode*)malloc(sizeof(*p));
        p->val = nums[i];
        p->next = NULL;
        if (head == NULL)
        {
            head = p;
            prev = head;
        }
        else
        {
            prev->next = p;
            prev = p;
        }
    }
    return head;
}
void printList(ListNode *head)
{
  ListNode *p = head;
    while (p != NULL)
    {
        printf("%d->", p->val);
        p = p->next;
    }
    printf("null\n");
}
int main()
{
    struct ListNode *head;
    int count;
    int head1[] = {1,2,3,3,4,4,5};
  Test(head1)
    int head2[] = {1,1,1,2,3};
  Test(head2)
    return 0;
}


输出:

1->2->3->3->4->4->5->null

1->2->5->null

1->1->1->2->3->null

2->3->null

目录
相关文章
|
5月前
(剑指offer)18、删除链表的节点—22、链表中倒数第K个节点—25、合并两个排序的链表—52、两个链表的第一个公共节点(2021.12.07)
(剑指offer)18、删除链表的节点—22、链表中倒数第K个节点—25、合并两个排序的链表—52、两个链表的第一个公共节点(2021.12.07)
71 0
|
5月前
|
算法
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
54 0
|
7月前
|
存储 算法
LeetCode第83题删除排序链表中的重复元素
文章介绍了LeetCode第83题"删除排序链表中的重复元素"的解法,使用双指针技术在原链表上原地删除重复元素,提供了一种时间和空间效率都较高的解决方案。
LeetCode第83题删除排序链表中的重复元素
|
7月前
|
存储 算法 Java
LeetCode初级算法题:反转链表+统计N以内的素数+删除排序数组中的重复项Java详解
LeetCode初级算法题:反转链表+统计N以内的素数+删除排序数组中的重复项Java详解
61 0
|
9月前
|
存储 人工智能 测试技术
每日练习之排序——链表的合并;完全背包—— 兑换零钱
每日练习之排序——链表的合并;完全背包—— 兑换零钱
52 2
|
9月前
|
存储 SQL 算法
LeetCode 83题:删除排序链表中的重复元素【面试】
LeetCode 83题:删除排序链表中的重复元素【面试】
|
9月前
|
存储 SQL 算法
LeetCode 题目 82:删除排序链表中的重复元素 II
LeetCode 题目 82:删除排序链表中的重复元素 II
|
23天前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
2天前
|
设计模式 安全 C++
【C++进阶】特殊类设计 && 单例模式
通过对特殊类设计和单例模式的深入探讨,我们可以更好地设计和实现复杂的C++程序。特殊类设计提高了代码的安全性和可维护性,而单例模式则确保类的唯一实例性和全局访问性。理解并掌握这些高级设计技巧,对于提升C++编程水平至关重要。
31 16
|
6天前
|
安全 C++
【c++】继承(继承的定义格式、赋值兼容转换、多继承、派生类默认成员函数规则、继承与友元、继承与静态成员)
本文深入探讨了C++中的继承机制,作为面向对象编程(OOP)的核心特性之一。继承通过允许派生类扩展基类的属性和方法,极大促进了代码复用,增强了代码的可维护性和可扩展性。文章详细介绍了继承的基本概念、定义格式、继承方式(public、protected、private)、赋值兼容转换、作用域问题、默认成员函数规则、继承与友元、静态成员、多继承及菱形继承问题,并对比了继承与组合的优缺点。最后总结指出,虽然继承提高了代码灵活性和复用率,但也带来了耦合度高的问题,建议在“has-a”和“is-a”关系同时存在时优先使用组合。
35 6