2021-12-24每日刷题打卡
力扣——每日一题
剑指 Offer 36. 二叉搜索树与双向链表
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。
为了让您更好地理解问题,以下面的二叉搜索树为例:
我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。
下图展示了上面的二叉搜索树转化成的链表。“head” 表示指向链表中有最小元素的节点。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jtGuxNp8-1640356317346)(https://assets.leetcode.com/uploads/2018/10/12/bstdllreturndll.png)]
特别地,我们希望可以就地完成转换操作。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继。还需要返回链表中的第一个节点的指针。
/*
// Definition for a Node.
class Node {
public:
int val;
Node* left;
Node* right;
Node() {}
Node(int _val) {
val = _val;
left = NULL;
right = NULL;
}
Node(int _val, Node* _left, Node* _right) {
val = _val;
left = _left;
right = _right;
}
};
*/
class Solution {
public:
Node*head,*tail;
Node* treeToDoublyList(Node* root) {
if(!root)return head;
dfs(root);
head->left=tail;
tail->right=head;
return head;
}
void dfs(Node*root)
{
if(!root)return;
dfs(root->left);
if(tail)
tail->right=root;
else
head=root;
root->left=tail;
tail=root;
dfs(root->right);
}
};
剑指 Offer 45. 把数组排成最小的数
输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
示例 1:
输入: [10,2]
输出: "102"
这里就是对数组进行排序,把数字a,b转换成字符串后拼接,判断是a+b的数小还是b+a的数大,把更小的组合放在数组的前面,比如10和2,102比210小,所以排序后10就放在2的前面,当数组排完序后,用字符串遍历数组的元素,并将它们拼接起来。
class Solution {
public:
static bool cmp(const int& a, const int& b)
{
string num1 = to_string(a)+to_string(b), num2 = to_string(b) + to_string(a);
if (num1 < num2)
return true;
else return false;
}
string minNumber(vector<int>& nums) {
sort(nums.begin(), nums.end(), cmp);
string str;
for (auto i : nums)
str += to_string(i);
return str;
}
};
剑指 Offer 61. 扑克牌中的顺子
从若干副扑克牌中随机抽 5 张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为 14。
示例 1:
输入: [1,2,3,4,5]
输出: True
对数组先进行排序,然后遍历数组,拿一个变量ans记录0的数量,开始遍历数组,当遇到0时ans++,当遇到当前数和下个数相同且当前数不为0时,已经说明不能组成顺子了(顺子里怎么会有相同的数),直接返回false;当遇到当前数+1不等于下一个数时,把ans的值减去nums[i-1]-nums[i]-1(两数之间的空插用0来代替,比如5到8,中间需要2个0),如果剪完后ans小于0,则说明不能组成顺子,返回false。如果遍历完数组还没返回false,就返回true。
class Solution {
public:
bool isStraight(vector<int>& nums) {
sort(nums.begin(),nums.end());
int ans=0;
for(int i=0;i<4;i++)
{
if(nums[i]==nums[i+1]&&nums[i]!=0)return false;
if(nums[i]==0)ans++;
else if(nums[i]+1!=nums[i+1])
{
ans-=nums[i+1]-nums[i]-1;
if(ans<0)return false;
}
}
return true;
}
};
{
ans-=nums[i+1]-nums[i]-1;
if(ans<0)return false;
}
}
return true;
}
};