Leetcode 刷题记录(一) 1/17/2018

128. Longest Consecutive Sequence

Given an unsorted array of integers, find the length of the longest consecutive elements sequence.

For example,
Given [100, 4, 200, 1, 3, 2],
The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4.

Your algorithm should run in O(n) complexity.

思路一:In this method, it iterates through the array while maintaining a HashMap whose key is the distinct numbers in input array and value is so far the longest consecutive subsequence starting at the number in key. We only update non-duplicate numbers and the newly added number joints its left consecutive subsequence and right consecutive subsequence to update the maximum length. 

class Solution {
    public int longestConsecutive(int[] nums) {
        int result = 0;
        HashMap<Integer,Integer> map = new HashMap<Integer,Integer> ();
        for(int num : nums) {
            if(!map.containsKey(num)) {
                int left = 0, right = 0, sum = 0;
                if(map.containsKey(num - 1)) left = map.get(num - 1);
                if(map.containsKey(num + 1)) right = map.get(num + 1);
                sum = left + right + 1;
                map.put(num, 1);
                result = Math.max(result, sum);
               
                map.put(num - left, sum);         //update both ends
                map.put(num + right, sum);
               
            }else
                continue;    //only care about non-duplicate elements
        }        
        return result;
    }
}

思路二:this method uses HashSet and has less interaction with the hash structure, making it a little bit faster. It firstly iterates through the array and store all distinct numbers in HashSet and then iterates the array again to remove all consecutive subsequence while updating the longest length.

class Solution {
   
public int longestConsecutive(int[] nums) {
       
int res = 0;
        Set<Integer> s =
new HashSet<Integer>();
       
for (int num : nums) s.add(num);
       
for (int num : nums) {
           
if (s.remove(num)) {
               
int pre = num - 1, next = num + 1;
               
while (s.remove(pre)) --pre;
               
while (s.remove(next)) ++next;
                res = Math.max(res, next - pre -
1);
            }
        }
       
return res;
    }
}


经验教训: 由于之前做过很多用到假哈希表(int[ ] map)的题,第一反应是创建一个数组map存储所有出现过的元素,但是码完发现这个方法根本无法应对数组长度越界的问题:在java中,array的最大长度在Integer.MAX_VALUE附近,因此若原题中未出现对数据范围的限定,数组map一般是不可以使用的。此外,在实现这两个方法时,有些边界问题十分容易出错,后来发现在纸上写写画画一些小规模的问题十分有助于梳理整个过程。

56. Merge Intervals

Given a collection of intervals, merge all overlapping intervals.

For example,
Given [1,3],[2,6],[8,10],[15,18],
return [1,6],[8,10],[15,18].

思路一:重写Comparator中的compare方法,再利用Collections.sort(<T>,comparator<T>) 对ADT进行排序,排序后依次融合所有交叠区间。

class Solution {
    public List<Interval> merge(List<Interval> intervals) {
        if(intervals.size() <= 1) return intervals;
        List<Interval> result = new ArrayList<>();
        Comparator comp = new Comparator<Interval>() {     //overwrite the compare() method and instantiate a comparator obj
            public int compare(Interval o1, Interval o2) {
                return o1.start - o2.start;
            }
        };
        Collections.sort(intervals, comp);
        int maxReach = intervals.get(0).end, curPos = intervals.get(0).start;
        for(int i = 0; i < intervals.size(); i ++) {
            if(maxReach >= intervals.get(i).start) {
                maxReach = Math.max(maxReach,intervals.get(i).end);
            }
            else {
                result.add(new Interval(curPos,maxReach));
                curPos = intervals.get(i).start;
                maxReach = intervals.get(i).end;
            }
        }
        result.add(new Interval(curPos,maxReach));   
        return result;
    }
}
经验教训:1.一开始又想到了int[] map,然而这个题没有限定范围且那样处理耗费空间太大;2.第一次写的时候,没有注意到最后一个区间无法加入结果list,应该注意在设计循环时先全面考虑好开头,中间,结尾三个位置是否会执行所需的效果,缺一不可。

Leetcode 680 Valid Palindrome II
思路一:很简单的一道题,需要注意的是遇到不同时,left + 1 和 right - 1都需考虑在内,而且为或的关系
class Solution {
   
public boolean validPalindrome(String s) {
char [] chars = s.toCharArray();
int left = 0 , right = chars.length - 1 ;
while (left < right) {
if (chars[left] != chars[right]) {
return isPalindrome(chars, left + 1 , right) || isPalindrome(chars, left, right - 1 );
}
left++;
right--;
}
return true ;
}
public boolean isPalindrome(char[] chars, int start, int end) {
while (start < end) {
if (chars[start] != chars[end]) {
return false ;
}
start++;
end--;
}
return true ;
}
}

287.Find the Duplicate Number

思路一:这个是一道linkedlist有环如何找entry point的题:快指针每次走两步,慢指针每次走一步,等他们相遇时一定在环内。此时,立刻从起点再发一个慢指针,新旧慢指针下一的相遇即在环的entry point.题目的思考角度很新颖,但这个用linkedlist解array题的思路有很多限制条件,普适性较差。

class Solution {
    public int findDuplicate(int[] nums) {
        if(nums.length > 1) {
            int slow = nums[0];
            int fast = nums[nums[0]];
           
            while(slow != fast) {
                slow = nums[slow];
                fast = nums[nums[fast]];
            }
           
            int meeter = 0;
            while(meeter != slow) {
                slow = nums[slow];
                meeter = nums[meeter];
            }
           
            return slow;
        }else
            return -1;
    }
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值