Leetcode-Java(四)

31. Next Permutation

分三步:
https://leetcode.com/problems/next-permutation/solution/
1、首先找到相邻的两个元素,前面一个元素值小于后面一个元素值,即nums[i] < nums[i+1] 因为数组是按逆序排序的话,直接倒置就可以了

2、此时i的位置确定了,接下来就是找到跟i元素交换的元素j,j元素应该是从后面开始第一个大于i元素的,此时交换i位置的元素和j位置的元素

3、第三步,此时i位置后面的元素是按逆序排序的,我们需要将其倒置

class Solution {
    public void nextPermutation(int[] nums) {
        public void nextPermutation(int[] nums) {
            int i = nums.length - 2;
            while (i >= 0 && nums[i + 1] <= nums[i]) {
                I--;
            }
            if (i >= 0) {
                int j = nums.length - 1;
                while (j >= 0 && nums[j] <= nums[i]) {
                    j--;
                }
                swap(nums, i, j);
            }
            reverse(nums, i + 1);
        }

        private void reverse(int[] nums, int start) {
            int i = start, j = nums.length - 1;
            while (i < j) {
                swap(nums, i, j);
                I++;
                j--;
            }
        }

        private void swap(int[] nums, int i, int j) {
            int temp = nums[I];
            nums[i] = nums[j];
            nums[j] = temp;
        }
    }
}

32. Longest Valid Parentheses

动态规划

class Solution {
    public int longestValidParentheses(String s) {
        int maxans = 0;
        int dp[] = new int[s.length()];
        for (int i = 1; i < s.length(); i++) {
            if (s.charAt(i) == ')') {
                if (s.charAt(i - 1) == '(') {
                    dp[i] = (i >= 2 ? dp[i - 2] : 0) + 2;
                } else if (i - dp[i - 1] > 0 && s.charAt(i - dp[i - 1] - 1) == '(') {
                    dp[i] = dp[i - 1] + ((i - dp[i - 1]) >= 2 ? dp[i - dp[i - 1] - 2] : 0) + 2;
                }
                maxans = Math.max(maxans, dp[i]);
            }
        }
        return maxans;
    }
}

使用栈

class Solution {
    public int longestValidParentheses(String s) {
        int maxres =0;
        Stack<Integer> stack = new Stack<Integer>();
        stack.push(-1);
        for(int i=0;i<s.length();i++){
            if(s.charAt(i)=='(')
                stack.push(i);
            else{
                stack.pop();
                if(stack.empty())
                    stack.push(i);
                else
                    maxres = Math.max(maxres,i-stack.peek());
            }
        }
        return maxres;
    }
}

33. Search in Rotated Sorted Array

二分查找的思路,要想清楚各种情况

class Solution {
    public int search(int[] nums, int target) {
        if(nums.length==0)
            return -1;
        int left = 0;
        int right = nums.length - 1;
        while(left <= right){
            int mid = (right-left) / 2 + left;
            if(nums[mid]==target)
                return mid;
            else{
                if(mid==left){
                    left ++;
                }
                else if(nums[mid] > nums[left]){
                    if(target>nums[mid])
                        left++;
                    else if(target>=nums[left])
                        right--;
                    else
                        left ++;
                }
                else{
                    if(target < nums[mid])
                        right--;
                    else if(target <= nums[right])
                        left ++;
                    else
                        right--;
                }         
            }
        }
        return -1;
    }
}

34. Search for a Range

用两次二分查找分别找到最左边和最右边的索引。

class Solution {
    public int[] searchRange(int[] nums, int target) {
        int[] res = new int[]{-1,-1};
        if(nums.length==0)
            return res; 
        int left = 0;int right=nums.length-1;
        while(left<=right){
            int mid = (right-left) / 2 + left;
            if(nums[mid]>=target)
                right--;
            else
                left++;
        }
        if(left<nums.length && nums[left]==target)
            res[0]=left;
        else
            return res;
        left = 0;right=nums.length-1;
        while(left<=right){
            int mid = (right-left) / 2 + left;
            if(nums[mid]<=target)
                left++;
            else
                right--;
        }
        if(right>=0 && nums[right]==target)
            res[1]=right;
        return res;
    }
}

35. Search Insert Position

即二分查找

class Solution {
    public int searchInsert(int[] nums, int target) {
        if(nums.length==0)
            return 0;
        int left = 0;
        int right = nums.length-1;
        while(left<=right){
            int mid = (right-left)/2 + left;
            if(nums[mid]==target)
                return mid;
            else if(nums[mid]>target)
                right = mid - 1 ;
            else
                left = mid + 1;
        }
        return left;
    }
}

36. Valid Sudoku

一个合法的九宫格要满足每行每列以及每个3*3的小正方形中都有1-9这9个数字。

我们循环九次,在每次循环中利用HashSet判断每列每行以及每个正方形中有没有重复数字即可:

class Solution {
    public boolean isValidSudoku(char[][] board) {
        for(int i = 0; i<9; i++){
            HashSet<Character> rows = new HashSet<Character>();
            HashSet<Character> columns = new HashSet<Character>();
            HashSet<Character> cube = new HashSet<Character>();
            for (int j = 0; j < 9;j++){
                if(board[i][j]!='.' && !rows.add(board[i][j]))
                    return false;
                if(board[j][i]!='.' && !columns.add(board[j][I]))
                    return false;
                int RowIndex = 3*(i/3);
                int ColIndex = 3*(i%3);
                if(board[RowIndex + j/3][ColIndex + j%3]!='.' && !cube.add(board[RowIndex + j/3][ColIndex + j%3]))
                    return false;
            }
        }
        return true;
    }
}

37. Sudoku Solver

回溯法

public class Solution {
    public void solveSudoku(char[][] board) {
        if(board == null || board.length == 0)
            return;
        solve(board);
    }
    
    public boolean solve(char[][] board){
        for(int i = 0; i < board.length; i++){
            for(int j = 0; j < board[0].length; j++){
                if(board[i][j] == '.'){
                    for(char c = '1'; c <= '9'; c++){//trial. Try 1 through 9
                        if(isValid(board, i, j, c)){
                            board[i][j] = c; //Put c for this cell
                            
                            if(solve(board))
                                return true; //If it's the solution return true
                            else
                                board[i][j] = '.'; //Otherwise go back
                        }
                    }
                    
                    return false;
                }
            }
        }
        return true;
    }
    
    private boolean isValid(char[][] board, int row, int col, char c){
        for(int i = 0; i < 9; i++) {
            if(board[i][col] != '.' && board[i][col] == c) return false; //check row
            if(board[row][i] != '.' && board[row][i] == c) return false; //check column
            if(board[3 * (row / 3) + i / 3][ 3 * (col / 3) + i % 3] != '.' && 
board[3 * (row / 3) + i / 3][3 * (col / 3) + i % 3] == c) return false; //check 3*3 block
        }
        return true;
    }
}

39. Combination Sum

回溯法,注意直接add arr是不行的。

class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> res = new LinkedList<>();
        if(candidates==null || candidates.length==0 || target<=0)
            return res;
        Arrays.sort(candidates);
        slove(res,candidates,0,new ArrayList<Integer>(),target);
        return res;
        
    }
    public static void slove(List<List<Integer>> res,int[] candidates,int start,ArrayList<Integer> arr,int target){
        if(target==0){
            //直接add arr是不行的
            res.add(new ArrayList<>(arr));
            return;
        }
        if(target<0)
            return;
        for(int i=start;i<candidates.length;i++){
            arr.add(candidates[I]);
            slove(res,candidates,i,arr,target-candidates[I]);
            arr.remove(arr.size()-1);
        }
    }
}

40. Combination Sum II

仍然是回溯法,39题的一个变形

class Solution {
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        List<List<Integer>> res = new LinkedList<>();
        if(candidates==null || candidates.length==0 || target<=0)
            return res;
        Arrays.sort(candidates);
        slove(res,candidates,0,new ArrayList<Integer>(),target);
        return res;
        
    }
    public static void slove(List<List<Integer>> res,int[] candidates,int start,ArrayList<Integer> arr,int target){
        if(target==0){
            //直接add arr是不行的
            res.add(new ArrayList<>(arr));
            return;
        }
        if(target<0)
            return;
        for(int i=start;i<candidates.length;i++){
            if(i>start && candidates[i]==candidates[i-1])
                continue;
            arr.add(candidates[i]);
            slove(res,candidates,i+1,arr,target-candidates[i]);
            arr.remove(arr.size()-1);
        }
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容

  • 背景 一年多以前我在知乎上答了有关LeetCode的问题, 分享了一些自己做题目的经验。 张土汪:刷leetcod...
    土汪阅读 12,723评论 0 33
  • LeetCode 刷题随手记 - 第一部分 前 256 题(非会员),仅算法题,的吐槽 https://leetc...
    蕾娜漢默阅读 17,685评论 2 36
  • 1. Two Sum 用hash可以得到O(n)时间的解法,用python中的enumerate函数,可以获得元素...
    Morphiaaa阅读 424评论 0 0
  • 326. Power of Three Given an integer, write a function to...
    跑者小越阅读 2,126评论 0 1
  • 2017再见。 2018你好。 唯有努力是出路。
    缄默与我阅读 225评论 0 4