148. Sort List\191. Number of 1 Bits\476. Number Complement\342. Power of Four

题目描述

Sort a linked list in O(n log n) time using constant space complexity.

对一个链表进行排序,时间复杂度为O(n log n),空间复杂度为O(1),所以这道题目的限制还是比较多。

由于链表的索引不是很方便,所以首先可以想到使用归并排序,那么时间复杂度为O(n log n)。然后又因为空间复杂度为O(1),那么对于指针的使用的要求比较高。需要进行较为复杂的指针重定向。

总的思路呢就是递归排序,排好最小单位以后然后再归并。这里呢需要注意的是如果单独排两个链表很简单,但是排多个链表的时候,需要想到怎么把前后的链表串联起来?以及如果判断边界?

前后字符串的串联就是使用返回头指针,再归并,再返回头指针。

判断边界这里使用二分快慢指针的时候,把中间节点的后继置为NULL,做归并的时候就更加方便不需要特意加入条件判断。

代码实现

代码效率还行,击败了68%左右的C++。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
 /**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */

class Solution {
public:
    ListNode* findMidListNode(ListNode* head) {
        if(!head || !head->next) return NULL;
        ListNode *p1 = head, *p2 = head->next; //tail?head:head->next;
        while(p2 != NULL && p2->next != NULL) {
            p2 = p2->next->next;
            p1 = p1->next;
        }
        p2 = p1->next;
        p1->next = NULL;
        return p2;
    }

    ListNode* Merge(ListNode* p1, ListNode* p2) {
        ListNode* head = new ListNode(0);
        ListNode* cur = head;
        while(p1 != NULL && p2 != NULL) {
            if(p1->val > p2->val) {
                cur->next = p2;
                cur = p2;
                p2 = p2->next;
            }    
            else {
                cur->next = p1;
                cur = p1;
                p1 = p1->next;
            }
        }
        cur->next = p1?p1:p2;
        return head->next;
    }

    ListNode* SortAndMerge(ListNode* head) {
        if(!head || !head->next) return head;

        ListNode* mid = findMidListNode(head);
        ListNode* p1 = SortAndMerge(head);
        ListNode* p2 = SortAndMerge(mid);
        return Merge(p1, p2);
    }

    ListNode* sortList(ListNode* head) {
        if(!head || !head->next) return head;
        return SortAndMerge(head);
    }
};

191. Number of 1 Bits

description

Write a function that takes an unsigned integer and returns the number of ’1’ bits it has (also known as the Hamming weight).

For example, the 32-bit integer ’11’ has binary representation 00000000000000000000000000001011, so the function should return 3.

implementation

This problem is very easy, we just shift the number and use operation & to get the lowest bit, if it’s 1 we add 1 to the result. Then shift the number by one bit until the shifted number is larger than 0.

class Solution {
public:
    int hammingWeight(uint32_t n) {
        int res = 0;
        while(n > 0) {
            res += n&1;
            n = n >> 1;
        }
        return res;
    }
};

476. Number Complement

description

Given a positive integer, output its complement number. The complement strategy is to flip the bits of its binary representation.

Note:
The given integer is guaranteed to fit within the range of a 32-bit signed integer.
You could assume no leading zero bit in the integer’s binary representation.
Example 1:

Input: 5
Output: 2
Explanation: The binary representation of 5 is 101 (no leading zero bits), and its complement is 010. So you need to output 2.

Example 2:

Input: 1
Output: 0
Explanation: The binary representation of 1 is 1 (no leading zero bits), and its complement is 0. So you need to output 0.

Here you need aware that the number is positive, and U have no need to worry about the non-positive situation as the signed shift.

implementation

1 the number is larger than 0 go to 2, otherwise break and return result.
2 get the reverse least significant bit of number and shift the bit to left with count.
3 shift number to right by one bit and count plus
4 go to step 1.

The code is showing below:

class Solution {
public:
    int findComplement(int num) {
        int res = 0, ind = 0;
        while(num > 0) {
            res |= (~num & 1) << ind;
            num = num >> 1;
            ind++;
        }
        return res;
    }
};

342. Power of Four

description

Given an integer (signed 32 bits), write a function to check whether it is a power of 4.

Example:
Given num = 16, return true. Given num = 5, return false.

Follow up: Could you solve it without loops/recursion?

Power of 4 is has the feature that the padding zero is double

implementation

The algorithm runs below:

1 get the least two bit of the number a and left number num
2 if a is zero and num is 1, return true
if a is 1 and num is 0 return true
if num is zero and a is not 1 return false
3 go to step 1

class Solution {
public:
    bool isPowerOfFour(int num) {
        if(num <= 0) return false;
        int lower = num&3;

        for(int i = 0; i < 16; i++) {
            num = num >> 2;
            if((num && lower) || (num == 0 && lower != 1)) return false;
            else if((num == 1 && lower == 0) || (num == 0 && lower == 1)) return true;
            lower = num&3;
        }
        return true;
    }
};

这道题目我还看到了非常变态的做法:

class Solution {
public:
    bool isPowerOfFour(int num) {
        double n = num;
        return (*(long*)&n & 0x801FFFFFFFFFFFFF) == 0x10000000000000;
    }
};

当然还有:

class Solution {
public:
    bool isPowerOfFour(int num) {
        return num > 0 && (num & (num - 1)) == 0 && (num - 1) % 3 == 0;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值