LeetCode: Merge Two Sorted Lists, Remove Duplicates/Element, strStr()

来源:互联网 发布:js touchevent事件 编辑:程序博客网 时间:2024/05/30 04:41

Merge Two Sorted Lists

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} //C++11初始化列表 * }; */

先自己想一下。同时遍历两个list,每次将较小的值弹出,放入结果list。其中一个节点全部弹出后,另一个直接链接到结果list的结尾。
时间O(n),n是两个输入list的总长度
空间O(n)

"""1. Recursion时间O(n),n是两个输入list的总长度空间O(n)"""
"""2. Iteration和我们一开始的想法很像,但是不使用额外的空间保存计算结果,而是重新连接原有的两个list。时间O(n),n是两个输入list的总长度空间O(1)15 ms, beats 14.06%"""class Solution {public:    ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {        ListNode dummy(INT_MIN);        ListNode *tail = &dummy;        while (l1 && l2) {            if (l1->val < l2->val) {                tail->next = l1;                l1 = l1->next;            } else {                tail->next = l2;                l2 = l2->next;            }            tail = tail->next;        }        tail->next = l1 ? l1 : l2;        return dummy.next;    }};

Remove Duplicates from Sorted Array
Given a sorted array, remove the duplicates in-place such that each element appear only once and return the new length.
It doesn’t matter what you leave beyond the new length.

先自己思考一下。
1,1,2,3,4
1,2,1,3,4

1,1,2,2,3
1,2,1,2,3
inplace,且后面可以留无用的数据,直觉是用某种swap。在两个简单例子上试一试,遍历数组,每次数值不增加时,往后遍历直到数值增加(m处),然后和这个不增加的数字swap一下。然后从m+1处继续遍历。

一个紧凑的实现如下

"""1. 26 ms, 61.68%时间O(n)空间O(1)"""public:    int removeDuplicates(vector<int>& nums) {        int count = 0;        for(int i = 1; i < nums.size(); i++){            if(nums[i] == nums[i-1]) count++;            else nums[i-count] = nums[i]; //amazing        }        return nums.size()-count;    }

Remove Element
Given an array and a value, remove all instances of that value in-place and return the new length.

和前一题很像,代码如下

"""3 ms, beats 61.64%"""    int removeElement(vector<int>& nums, int val) {        int count = 0;        for(int i = 0; i < nums.size(); i++){            if(nums[i] == val) count++;            else nums[i-count] = nums[i]; //amazing        }        return nums.size()-count;    }

1,2,2,3
2
nums0 = nums0
nums1 = nums3
确实多做了一些赋值操作,注意The order of elements can be changed,所以当需要移除的值比较少时,还可以进一步减少操作的次数。

Now consider cases where the array contains few elements to remove. For example, nums = [1,2,3,5,4], val = 4. The previous algorithm will do unnecessary copy operation of the first four elements. Another example is nums = [4,1,2,3,5], val = 4. It seems unnecessary to move elements [1,2,3,5] one step left as the problem description mentions that the order of elements could be changed.

""" 6 ms, beats 8.10%"""    int removeElement(vector<int>& nums, int val) {        int size = nums.size();        for(int i = 0; i < size; i++){            if(nums[i] == val) {                nums[i] = nums[size-1];                size --;                i--; //用while能把i++ i--省掉            }        }        return size;    }
""" 6 ms"""    int removeElement(vector<int>& nums, int val) {        int size = nums.size();        for(int i = 0; i < size; i++){            if(nums[i] == val) {                for(int j=size-1; j>i; j--){                    if (nums[j] != val){                        nums[i] = nums[j];                        break;                    }                    size --;                }                size --;            }        }        return size;    }

理论上更好的算法时间变更长了,可能和测试集合有关吧。

Implement strStr()
Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
Input: haystack = “hello”, needle = “ll”
Output: 2
很简单。

"""1. 暴力搜素6 ms, beats 26.76%"""    int strStr(string haystack, string needle) {        int m = needle.length();        if (haystack.size() < m) return -1;        //(haystack.size() == 0 && m == 0) return 0;        for (int i=0; i<=haystack.length()-m; i++){            if (haystack.substr(i, m) == needle)                return i;        }        return -1;    }

上述程序乍一看很好,如果我们没有调用substr函数则更容易发现问题:在haystack.substr(i, m) == needle这步其实是逐位字符比较的。有啥问题参见【算法】KMP算法解析。
一个例子如下:

i: 0 1 2 3 4 5 6 7 8 9 0 1 2M: a b c d a b c d a b c d eN: a b c d e                 // 匹配四位成功后发现a、e不匹配i: 0 1 2 3 4 5 6 7 8 9 0 1 2M: a b c d a b c d a b c d eN:   a b c d e               // 发现 a、b不匹配i: 0 1 2 3 4 5 6 7 8 9 0 1 2M: a b c d a b c d a b c d eN:     a b c d e             // 发现 a、c不匹配i: 0 1 2 3 4 5 6 7 8 9 0 1 2M: a b c d a b c d a b c d eN:       a b c d e           // 发现 a、d不匹配i: 0 1 2 3 4 5 6 7 8 9 0 1 2M: a b c d a b c d a b c d eN:         a b c d e         // 匹配四位成功后发现a、e不匹配i: 0 1 2 3 4 5 6 7 8 9 0 1 2M: a b c d a b c d a b c d eN:           a b c d e       // 发现 a、b不匹配i: 0 1 2 3 4 5 6 7 8 9 0 1 2M: a b c d a b c d a b c d eN:             a b c d e     // 发现 a、c不匹配i: 0 1 2 3 4 5 6 7 8 9 0 1 2M: a b c d a b c d a b c d eN:               a b c d e   // 发现 a、d不匹配i: 0 1 2 3 4 5 6 7 8 9 0 1 2M: a b c d a b c d a b c d eN:                 a b c d e // 匹配成功
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 碰上职业打假的怎么办 遇到专业打假的怎么办 手机wifi被劫持怎么办 手机网页乱跳怎么办 老公说话不算话怎么办 编曲接不到活怎么办 电表显示跳闸黄灯怎么办 硫酸铬钾中毒怎么办 门锁能扭动却打不开怎么办 防盗门保险坏了怎么办 厦门工会卡过期怎么办 阴雨天被子受潮怎么办 衣服晾臭了怎么办 喷砂机油水分离泵有油怎么办 水太烫玻璃瓶盖打不开怎么办 玻璃罐的玻璃盖打不开怎么办? 开红酒没有开瓶器怎么办 手机卡突然坏了怎么办 滚筒洗衣机打不开门怎么办 全自动洗衣机门开不开怎么办 好期待评分不足怎么办 单片机数码管亮度低怎么办 猫的同轴灯不亮怎么办 楼下邻居太吵怎么办 冰箱冷却液内露怎么办 冷却水没有了会怎么办 金立m7信号不好怎么办 csgo凉了饰品怎么办 模型拟合度低怎么办 石膏线用发泡胶怎么办 电表上显示err10怎么办 电表显示欠压怎么办 tcl电视遥控器失灵怎么办 玩具汽车遥控器失灵怎么办 玩具车遥控丢了怎么办 按压扣坏了怎么办 电脑用不了鼠标怎么办 多肉上的肉虫子怎么办 警察被取消警衔怎么办 隐形眼镜带歪了怎么办 gta5正在加载慢怎么办