leetcode题解日练--2016.6.28

来源:互联网 发布:淘宝手机话费充值软件 编辑:程序博客网 时间:2024/05/08 06:38

编程日记,尽量保证每天至少3道leetcode题,仅此记录学习的一些题目答案与思路,尽量用多种思路来分析解决问题,不足之处还望指出。标红题为之后还需要再看的题目。

今日题目:1、反转比特位;2、移除链表元素;3、回文链表;4、最长公共前缀

190. Reverse Bits | Difficulty: Easy

Reverse bits of a given 32 bits unsigned integer.

For example, given input 43261596 (represented in binary as 00000010100101000001111010011100), return 964176192 (represented in binary as 00111001011110000010100101000000).

Follow up:
If this function is called many times, how would you optimize it?

Related problem: Reverse Integer

题意:给一个数字,逆转它的二进制表示位。
思路:
1、32次循环,每次循环都是现将res左移1位然后再加上num的最低位。
代码:
C++

class Solution {public:    uint32_t reverseBits(uint32_t n) {        uint32_t res=0;        for(int i=0;i<32;i++,n>>=1)        {            res=res<<1;            res |= n&1;        }        return res;    }};

结果:4ms

203. Remove Linked List Elements | Difficulty: Easy

Remove all elements from a linked list of integers that have value val.

Example
Given: 1 –> 2 –> 6 –> 3 –> 4 –> 5 –> 6, val = 6
Return: 1 –> 2 –> 3 –> 4 –> 5

题意:删除链表中值为val的元素。
思路:
直接从头开始,首先确定头的值不是val,然后逐个遍历,如果碰到值为val的节点则利用一个前节点(Prev)来删除当前的节点。不难,但是自己写的代码很丑,三次才AC,还是贴上来好了。
代码:
C++

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode* removeElements(ListNode* head, int val) {        ListNode *Prev,*Node;        if(!head)   return head;        while(head)        {            if(head->val==val)                head = head->next;            else                break;        }        Node = head;        Prev = NULL;        while(Node)        {            if(Node->val==val)              {                Prev->next = Node->next;                delete Node;                Node = Prev->next;            }            else            {                Prev = Node;                Node = Node->next;            }        }        return head;    }};

结果:36ms

2、参考了https://leetcode.com/discuss/47642/simple-and-elegant-solution-in-c的做法,用一个二级指针,指针指向的是节点,最初指针指向的是head节点。当指针指向的节点等于val的的时候,指针指向的节点直接赋值为下一个节点,也就相当于是删除了当前的节点;当指针指向的节点不等于val的时候,需要更改指针内存放的内容为下一个节点。进行下一次的判断直到指针的内容为空。

class Solution {public:    ListNode* removeElements(ListNode* head, int val) {        ListNode ** list = &head;        while(*list)        {            if((*list)->val==val)                *list = (*list)->next;            else                list = &(*list)->next;        }        return head;    }};

结果:32ms
第二次刷代码

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    ListNode* removeElements(ListNode* head, int val) {        if(head==NULL)  return NULL;        ListNode*pre = new ListNode(INT_MIN);        pre->next = head;        ListNode*cur = pre;        while(cur->next)        {            if(cur->next->val==val) cur->next = cur->next->next;            else    cur = cur->next;        }        return pre->next;    }};

结果:32ms

234. Palindrome Linked List | Difficulty: Easy

Given a singly linked list, determine if it is a palindrome.

Follow up:
Could you do it in O(n) time and O(1) space?

题意:给一个链表,判断是否是回文。O(N)的时间和O(1)的空间。
思路:
首先,因为链表是单向的,那么要判断回文就需要将第一个节点和最后一个节点比较,然后两个节点向中间靠拢。首先我们需要找到中间的节点,即不需要逆转的最后一个节点。当节点总数是奇数的时候,例如n=7,显然我们只需要比较前三个节点和后三个节点,第4个节点不需要移动,中间节点下标是(6-0)/2=3,当n=8的时候,需要比较前四个节点和后四个节点,第四个节点不需要移动,因此中间节点下标还是(7-0)/2 = 3。因此第一步就是找到中间结点。
其次,找到中间节点之后,需要将中间节点之后的节点逆序,然后从中间节点的下一个节点开始依次和头部节点相比较。
C++

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public:    bool isPalindrome(ListNode* head) {        if(head==NULL||head->next==NULL) return true;        ListNode*slow,*fast;        slow=head,fast = head;        while(fast->next!=NULL && fast->next->next!=NULL)        {            slow = slow->next;            fast = fast->next->next;        }        slow->next = ReverseList(slow->next);        while(slow->next!=NULL)        {            if(slow->next->val!=head->val)  return false;            slow = slow->next;            head = head->next;        }        return true;    }    ListNode* ReverseList(ListNode* head)    {        ListNode*Prev,*next;        Prev = NULL;        while(head!=NULL)        {         next = head->next;         head->next = Prev;         Prev = head;         head = next;        }        return Prev;    }};

结果:29ms

14. Longest Common Prefix | Difficulty: Easy

Write a function to find the longest common prefix string amongst an array of strings.

题意:求一组字符串的最长公共前缀
思路:
逐个字符开始比较,先比较第0个字符是否符合,知道找到不符合的位为止返回前缀。
代码:
C++

class Solution {public:    string longestCommonPrefix(vector<string>& strs) {        string prefix = "";        if(strs.size()<=0)  return prefix;        //k代表判断的前缀字符数,从第0个字符开始,判断每一个strs的元素的第k位是否相等,如果全部相等了则最长公共前缀加1        for(int k = 0;k<strs[0].size();k++)        {            //i代表第i个字符串,每次循环的i需要小于strs的个数以及至少为k位,因为之前的前缀已经有k位了,某个字符串没有达到k位那么不必继续计算了            int i=1;            for(;i<strs.size()&&strs[i].size()>k;i++)            {                if(strs[i][k]!=strs[0][k])  return prefix;            }             if(i==strs.size())     prefix +=strs[0][k];        }        return prefix;    }};

结果:6ms

2、KMP解法

class Solution {public:    int strStr(string haystack, string needle) {        int hsize = haystack.size();        int nsize = needle.size();        if(nsize==0 ) return 0;        int *next = new int[nsize];        memset(next,0,sizeof(int)*nsize);        //build the table        for(int i=1,j=0;i<nsize;)        {            if(needle[i]!=needle[j])            {                if(j>0)                     j=next[j-1];                else                    i++;            }            else            {                next[i] = j+1;                i++;                j++;            }        }        //match str        for(int str=0,pat=0;str<hsize;)        {            if(haystack[str]==needle[pat])              {                if(pat==nsize-1)  return str-nsize+1;                else    {str++;pat++;}            }            else            {                if(pat==0)  str++;                else pat = next[pat-1];            }        }        delete[]next;        return -1;    }};

结果:4ms

0 0
原创粉丝点击