leetcode(86-90)

19 篇文章 0 订阅

86. 分隔链表

给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。

你应当保留两个分区中每个节点的初始相对位置。

示例:

输入: head = 1->4->3->2->5->2, x = 3
输出: 1->2->2->4->3->5
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* partition(ListNode* head, int x) {
        if(!head) return NULL;
        ListNode *h1=new ListNode(0),*p=h1,*h2=new ListNode(0),*q=h2;
        while(head){
            if(head->val < x){
                p->next=head;
                p=p->next;
            } else {
                q->next=head;
                q=q->next;
            }
            head=head->next;
        }
        p->next=h2->next;
        q->next=NULL;
        return h1->next;
    }
};

87. 扰乱字符串

给定一个字符串 s1,我们可以把它递归地分割成两个非空子字符串,从而将其表示为二叉树。

下图是字符串 s1 = "great" 的一种可能的表示形式。

    great
   /    \
  gr    eat
 / \    /  \
g   r  e   at
           / \
          a   t

在扰乱这个字符串的过程中,我们可以挑选任何一个非叶节点,然后交换它的两个子节点。

例如,如果我们挑选非叶节点 "gr" ,交换它的两个子节点,将会产生扰乱字符串 "rgeat" 。

    rgeat
   /    \
  rg    eat
 / \    /  \
r   g  e   at
           / \
          a   t

我们将 "rgeat” 称作 "great" 的一个扰乱字符串。

同样地,如果我们继续将其节点 "eat" 和 "at" 进行交换,将会产生另一个新的扰乱字符串 "rgtae" 。

    rgtae
   /    \
  rg    tae
 / \    /  \
r   g  ta  e
       / \
      t   a

我们将 "rgtae” 称作 "great" 的一个扰乱字符串。

给出两个长度相等的字符串 s1 和 s2,判断 s2 是否是 s1 的扰乱字符串。

示例 1:

输入: s1 = "great", s2 = "rgeat"
输出: true

示例 2:

输入: s1 = "abcde", s2 = "caebd"
输出: false
class Solution {
public:
    bool isScramble(string s1, string s2) {
        if(s1.size() != s2.size()) return false;
        int len=s1.size();
        int cnt[256]={0};
        for(int i=0; i<len; i++) cnt[s1[i]]++;
        for(int i=0; i<len; i++){
            if(--cnt[s2[i]] < 0) return false;
        }
        if(len<=3) return true;
        for(int k=1; k<len; k++){
            if((isScramble(s1.substr(0,k), s2.substr(0,k))
               && isScramble(s1.substr(k,len), s2.substr(k,len)))
               || (isScramble(s1.substr(0,k), s2.substr(len-k,len))
               && isScramble(s1.substr(k,len), s2.substr(0,len-k))))
                return true;
        }
        return false;
    }
};

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]
class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        m--;
        n--;
        int i=m+n+1;
        while(m>=0 && n>=0){
            if(nums1[m] > nums2[n]) {
                nums1[i]=nums1[m];
                m--;
            } else {
                nums1[i]=nums2[n];
                n--;
            }
            i--;
        }
        while(m>=0) {
            nums1[i]=nums1[m];
            m--;
            i--;
        }
        while(n>=0){
            nums1[i]=nums2[n];
            i--;
            n--;
        }
        return;
    }
};

89. 格雷编码

格雷编码是一个二进制数字系统,在该系统中,两个连续的数值仅有一个位数的差异。

给定一个代表编码总位数的非负整数 n,打印其格雷编码序列。格雷编码序列必须以 0 开头。

示例 1:

输入: 2
输出: [0,1,3,2]
解释:
00 - 0
01 - 1
11 - 3
10 - 2

对于给定的 n,其格雷编码序列并不唯一。
例如,[0,2,3,1] 也是一个有效的格雷编码序列。

00 - 0
10 - 2
11 - 3
01 - 1

示例 2:

输入: 0
输出: [0]解释: 我们定义格雷编码序列必须以 0 开头。给定编码总位数为 n 的格雷编码序列,其长度为 2nn = 0 时,长度为 20 = 1。因此,当 n = 0 时,其格雷编码序列为 [0]。
class Solution {
public:
    vector<int> grayCode(int n) {
        vector<int> res{0};
        for (int i = 0; i < n; ++i) {
            int size = res.size();
            for (int j = size - 1; j >= 0; --j) {
                res.push_back(res[j] | (1 << i));
            }
        }
        return res;
    }
};

90. 子集 II

给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

说明:解集不能包含重复的子集。

示例:

输入: [1,2,2]
输出:
[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]
class Solution {
public:
    vector<vector<int>> subsetsWithDup(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        vector<vector<int>> res;
        vector<int> path;
        subSet(nums, 0, path, res);
        return res;
    }
    void subSet(vector<int>& nums, int index, vector<int>& path, vector<vector<int>>& res){
        res.push_back(path);
        for(int i=index; i<nums.size(); i++){
            if(index<i && nums[i]==nums[i-1]) continue;
            path.push_back(nums[i]);
            subSet(nums, i+1, path, res);
            path.pop_back();
        }
    }
};

(以上题目均摘自leetcode)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值