算法刷题记录(LeetCode 61-90)

61. Rotate List

    public ListNode rotateRight(ListNode head, int k) {
        if(head==null||k==0){
            return head;
        }
        ListNode fast=head;
        ListNode slow=head;
        int initialK=k;
        int count=0;
        ListNode prev=fast;
        ListNode fastPrev=fast;
        while(fast!=null&&k>0){
            prev=fast;
            fast=fast.next;
            k--;
            count++;
        }
        if(fast==null&&k==0){
            return head;
        }
        if(fast==null){
            k=initialK%count;
            if(k==0){
                return head;
            }
            fast=head;
            while(fast!=null&&k>0){
                prev=fast;
                fast=fast.next;
                k--;
            }
        }
        while(fast!=null){
            prev=slow;
            slow=slow.next;
            fastPrev=fast;
            fast=fast.next;
        }
        prev.next=null;
        fastPrev.next=head;
        return slow;

    }

62. Unique Paths

class Solution {
    public int uniquePaths(int m, int n) {
        int[][] possiblePaths=new int[m][n];
        for(int i=0;i<m;i++){
            possiblePaths[i][n-1]=1;
        }
        for(int j=0;j<n;j++){
            possiblePaths[m-1][j]=1;
        }
        for(int i=m-2;i>=0;i--){
            for(int j=n-2;j>=0;j--){
                possiblePaths[i][j]=possiblePaths[i+1][j]+possiblePaths[i][j+1];
            }
        }
        return possiblePaths[0][0];

    }
}

63. Unique Paths II

    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        int row=obstacleGrid.length;
        int column=obstacleGrid[0].length;
        int[][] dp=new int[row][column];
        for (int i=column-1;i>=0;i--){
            if (obstacleGrid[row-1][i]==0){
                dp[row-1][i]=1;
            }
            else{
                break;
            }
        }
        for (int i=row-1;i>=0;i--){
            if (obstacleGrid[i][column-1]==1){
                break;
            }
            dp[i][column-1]=1;
        }
        for (int i=row-2;i>=0;i--){
            for (int j=column-2;j>=0;j--){
                if (obstacleGrid[i][j]==0){
                    dp[i][j]=dp[i+1][j]+dp[i][j+1];
                }
            }
        }
        return dp[0][0];
    }

64. Minimum Path Sum(Solved)

    public int minPathSum(int[][] grid) {
        int row=grid.length;
        int column=grid[0].length;
        int[][] costs=new int[row][column];
        costs[0][0]=grid[0][0];
        for(int i=1;i<row;i++){
            costs[i][0]=costs[i-1][0]+grid[i][0];
        }
        for(int j=1;j<column;j++){
            costs[0][j]=costs[0][j-1]+grid[0][j];
        }
        for(int i=1;i<row;i++){
            for(int j=1;j<column;j++){
                costs[i][j]=Math.min(costs[i-1][j],costs[i][j-1])+grid[i][j];
            }
        }
        return costs[row-1][column-1];
    }

66. Plus One

    public int[] plusOne(int[] digits) {
        digits[digits.length-1]++;
        ArrayList<Integer> res = new ArrayList<>();
        int carry = 0;
        for (int i = digits.length - 1; i >= 0; i--) {
            int val=digits[i]+carry;
            res.add(val%10);
            carry=val/10;
        }
        if (carry>0){
            res.add(1);
        }
        int[] res_arr=new int[res.size()];
        for (int i=0;i<res_arr.length;i++){
            res_arr[i]=res.get(res.size()-i-1);
        }
        return res_arr;
    }

68. Text Justification

class Solution {
    public List<String> fullJustify(String[] words, int maxWidth) {
        List<String> ans = new ArrayList<String>();
        int right = 0, n = words.length;
        while (true) {
            int left = right; // 当前行的第一个单词在 words 的位置
            int sumLen = 0; // 统计这一行单词长度之和
            // 循环确定当前行可以放多少单词,注意单词之间应至少有一个空格
            while (right < n && sumLen + words[right].length() + right - left <= maxWidth) {
                sumLen += words[right++].length();
            }

            // 当前行是最后一行:单词左对齐,且单词之间应只有一个空格,在行末填充剩余空格
            if (right == n) {
                StringBuffer sb = join(words, left, n, " ");
                sb.append(blank(maxWidth - sb.length()));
                ans.add(sb.toString());
                return ans;
            }

            int numWords = right - left;
            int numSpaces = maxWidth - sumLen;

            // 当前行只有一个单词:该单词左对齐,在行末填充剩余空格
            if (numWords == 1) {
                StringBuffer sb = new StringBuffer(words[left]);
                sb.append(blank(numSpaces));
                ans.add(sb.toString());
                continue;
            }

            // 当前行不只一个单词
            int avgSpaces = numSpaces / (numWords - 1);
            int extraSpaces = numSpaces % (numWords - 1);
            StringBuffer sb = new StringBuffer();
            sb.append(join(words, left, left + extraSpaces + 1, blank(avgSpaces + 1))); // 拼接额外加一个空格的单词
            sb.append(blank(avgSpaces));
            sb.append(join(words, left + extraSpaces + 1, right, blank(avgSpaces))); // 拼接其余单词
            ans.add(sb.toString());
        }
    }

    // blank 返回长度为 n 的由空格组成的字符串
    public String blank(int n) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < n; ++i) {
            sb.append(' ');
        }
        return sb.toString();
    }

    // join 返回用 sep 拼接 [left, right) 范围内的 words 组成的字符串
    public StringBuffer join(String[] words, int left, int right, String sep) {
        StringBuffer sb = new StringBuffer(words[left]);
        for (int i = left + 1; i < right; ++i) {
            sb.append(sep);
            sb.append(words[i]);
        }
        return sb;
    }
}

69. Sqrt(x)(Solved)

注意大数的上溢出( x 2 x^2 x2)

二分法计算

    public int mySqrt(int x) {
        int left=0;
        int right=x;
        int mid;
        long res;
        long y =x;
        while(left<right){
            mid=(left+right)/2;
            res=(long)Math.pow(mid,2);
            if(res==y){
                return mid;
            }
            if(res>y){
                right=mid-1;
            }
            else{
                left=mid+1;
            }
        }
        if(Math.pow(left,2)>x){
            return left-1;
        }
        return left;
    }

70. Climbing Stairs(Solved)

    public int climbStairs(int n) {
        int[] ways=new int[n+1];
        ways[1]=1;
        ways[0]=1;
        for(int i=2;i<=n;i++){
            ways[i]=ways[i-1]+ways[i-2];
        }
        return ways[n];
    }

72.Word Search

class Solution {
    static int row;
    static int column;
    public boolean exist(char[][] board, String word) {
        HashSet<List<Integer>> spotted=new HashSet<>();
        row=board.length;
        column=board[0].length;
        for(int i=0;i<row;i++){
            for(int j=0;j<column;j++){
                if(bfs(board,spotted,i,j,word,0)){
                    return true;
                }
            }
        }
        return false;
    }
    public boolean bfs(char[][] board,HashSet<List<Integer>> spotted,int i, int j,String word,int word_idx){
        if(word_idx>=word.length()){
            return true;
        }
        if(i<0||j<0||i>=row||j>=column||word.charAt(word_idx)!=board[i][j]||spotted.contains(List.of(i,j))){
            return false;
        }
        spotted.add(List.of(i,j));
        boolean res=bfs(board,spotted,i-1,j,word,word_idx+1)||bfs(board,spotted,i+1,j,word,word_idx+1)
                ||bfs(board,spotted,i,j-1,word,word_idx+1)||bfs(board,spotted,i,j+1,word,word_idx+1);
        spotted.remove(List.of(i,j));
        return res;

    }
}

74. Search a 2D Matrix(Sloved)

    public boolean searchMatrix(int[][] matrix, int target) {
        if(target<matrix[0][0]||target>matrix[matrix.length-1][matrix[0].length-1]){
            return false;
        }
        int row=matrix.length;
        int column = matrix[0].length;
        int start_row=0;
        int start_column=0;
        int end_row=row-1;
        int end_column=column-1;
        int mid_row=0;
        int mid_column=0;
        while (start_row<=end_row){
            mid_row=(end_row+start_row)>>1;
            if(start_row==end_row){
                break;
            }
            if(matrix[mid_row][end_column]<target){
                start_row=mid_row+1;
            }else if(matrix[mid_row][0]>target){
                end_row=mid_row-1;
            }else {
                break;
            }
        }
        while (start_column<=end_column){
            mid_column=(end_column+start_column)>>1;
            if(matrix[mid_row][mid_column]==target){
                return true;
            }
            else if(matrix[mid_row][mid_column]>target){
                end_column=mid_column-1;
            }
            else{
                start_column=mid_column+1;
            }
        }
        return false;
    }

76. Minimum Window Substring

这道题用JAVA完成时,一定要记住Integer是对象,平常能用==比较是因为-128 到 127 是直接在缓存池中的,超过这个数字的比较如果用==会返回false,一定要使用equals()方法。

    public String minWindow(String s, String t) {
        if (t.equals("") || s.equals("")) {
            return "";
        }
        int have = 0;
        HashMap<Character, Integer> needs = new HashMap<>();
        for (int i = 0; i < t.length(); i++) {
            needs.put(t.charAt(i), needs.getOrDefault(t.charAt(i), 0) + 1);
        }
        int needsNum = needs.size();
        int left = 0;
        int right = 0;
        int[] resIndex = {-1,-1};
        int minLen = Integer.MAX_VALUE;
        HashMap<Character, Integer> window = new HashMap<>();
        for (; right < s.length(); right++) {
            Character ch=s.charAt(right);
            if (needs.containsKey(ch)) {
                window.put(ch, window.getOrDefault(ch, 0) + 1);
                // 注意Integer是对象,要用equals比较
                if (window.get(ch).equals(needs.get(ch))) {
                    have++;
                }
            }
            while (have == needsNum) {
                if (minLen > right - left + 1) {
                    minLen = right - left + 1;
                    resIndex[0] = left;
                    resIndex[1] = right;
                }
                if (needs.containsKey(s.charAt(left))) {
                    window.put(s.charAt(left), window.get(s.charAt(left))-1);
                    if(window.get(s.charAt(left))<needs.get(s.charAt(left))){
                        have--;
                    }
                }
                left++;
            }
        }
        if(minLen==Integer.MAX_VALUE){
            return "";
        }
        return s.substring(resIndex[0],resIndex[1]+1);
    }

77. Combinations

public class Solution {
    public static List<List<Integer>> res=new ArrayList<>();
    public List<List<Integer>> combine(int n, int k) {
        res.clear();
        backTrack(new ArrayList<>(),1,n,k);
        return res;

    }
    public void backTrack(ArrayList<Integer> curr,int curr_element, int n,int remains){
        if (remains==0){
            res.add(new ArrayList<>(curr));
            return;
        }
        if (curr_element>n){
            return;
        }
        curr.add(curr_element);
        backTrack(curr, curr_element+1,n,remains-1);
        curr.remove(curr.size()-1);
        backTrack(curr,curr_element+1,n,remains);
    }
}

78. Subsets

    public static ArrayList<Integer> subset=new ArrayList<>();
    public List<List<Integer>> subsets(int[] nums) {
        subset.clear();
        List<List<Integer>> res=new ArrayList<>();
        bfs(nums,0,res);
        return res;


    }
    void bfs(int[] nums,int i,List<List<Integer>> res){
        if(i>=nums.length){
            List<Integer> clonedList =(ArrayList<Integer>) subset.clone();
            res.add(clonedList);
            return;
        }
        subset.add(nums[i]);
        bfs(nums,i+1,res);
        subset.remove(subset.size()-1);
        bfs(nums,i+1,res);

    }

80. Remove Duplicates from Sorted Array II

class Solution {
    public int removeDuplicates(int[] nums) {
        if (nums.length<=2){
            return nums.length;
        }
        int prev=nums[0];
        int counts=1;
        int left=1;
        int curr=1;
        while (curr<nums.length){
            if (nums[curr]==prev){
                counts++;
            }
            else {
                prev=nums[curr];
                counts=1;
            }
            if (counts>2){
                left--;
            }
            swap(nums,left,curr);
            left++;
            curr++;
        }
        return left;
    }
    public void swap(int[] arr,int i,int j){
        int temp=arr[i];
        arr[i]=arr[j];
        arr[j]=temp;
    }
}

81. Search in Rotated Sorted Array II

Binary 注意首先恢复二分性

class Solution {
    public boolean search(int[] nums, int t) {
        int n = nums.length;
        int l = 0, r = n - 1;
        // 恢复二段性
        while (l < r && nums[0] == nums[r]) r--;

        // 第一次二分,找旋转点
        while (l < r) {
            int mid = l + r + 1 >> 1;
            if (nums[mid] >= nums[0]) {
                l = mid;
            } else {
                r = mid - 1;
            }
        }
        
        int idx = n;
        if (nums[r] >= nums[0] && r + 1 < n) idx = r + 1;

        // 第二次二分,找目标值
        int ans = find(nums, 0, idx - 1, t);
        if (ans != -1) return true;
        ans = find(nums, idx, n - 1, t);
        return ans != -1;
    }
    int find(int[] nums, int l, int r, int t) {
        while (l < r) {
            int mid = l + r >> 1;
            if (nums[mid] >= t) {
                r = mid;
            } else {
                l = mid + 1;
            }
        }
        return nums[r] == t ? r : -1;
    }
}

82. Remove Duplicates from Sorted List II

    public ListNode deleteDuplicates(ListNode head) {
        ListNode dummy =new ListNode(-1111);
        dummy.next=head;
        ListNode prev=dummy;
        ListNode curr=head;
        while(curr!=null){
            while(curr.next!=null&&prev.next.val==curr.next.val){
                curr = curr.next;
            }
            if(prev.next==curr){
                prev=prev.next;
            }
            else{
                prev.next=curr.next;
            }
            curr=curr.next;
        }
        return dummy.next;

    }

83. Remove Duplicates from Sorted List

    public ListNode deleteDuplicates(ListNode head) {
        if (head==null){
            return null;
        }
        ListNode prev=head;
        ListNode curr=head.next;
        while (curr!=null){
            if (prev.val==curr.val){
                prev.next=curr.next;
                curr=curr.next;
            }
            else{
                prev=curr;
                curr=curr.next;
            }
        }
        return head;
    }

88. Merge Sorted Array

    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int i=m-1,j=n-1,last=m+n-1;
        while(i>=0&&j>=0){
            if(nums2[j]>nums1[i]){
                nums1[last]=nums2[j];
                j--;
                last--;
            }
            else{
                nums1[last]=nums1[i];
                i--;
                last--;
            }
        }
        while(j>=0){
            nums1[last]=nums2[j];
            last--;
            j--;
        }
    }

89. Gray Code

对于n:

n = 1 [0, 1]
n = 2 [00,01,11,10]
n = 3 [000, 001, 011, 010, 110, 111, 101, 100]

一位格雷码只有两个元素,【1, 0】
因为格雷码 n 每增加1,包含的数字会翻倍,这里我们设n位格雷码包含c个数,前一个n为 n ′ n' n,所以
c = 2 c ′ c = 2c' c=2c
所以这时n中的前c’个数是n’中的所有数字前面补0,相当于全部都是n`中的数字

n = 2  [ 00,  01,  11,  10] 
n = 3  [000, 001, 011, 010] (前四个数)

这时n中的后 c ′ c' c个数是 n ′ n' n中的所有数字前面补1,然后变为逆序

n = 2  [ 00,  01,  11,  10]1 [100, 101, 111, 110] 
逆  序 [110, 111, 101, 100] (后四个数)
结果拼接
 n = 3  [000, 001, 011, 010, 110, 111, 101, 100]

Induction

    public List<Integer> grayCode(int n) {
        List<Integer> res=new ArrayList<>();
        res.add(0);
        for (int i=1;i<=n;i++){
            int prev_size=res.size();
            for (int j=prev_size-1;j>=0;j--){
                res.add(res.get(j)|1<<(i-1));
            }
        }
        return res;
    }

Subsets II

Back Track

本质还是对是否跳过当前元素进行检索

class Solution {
    public List<List<Integer>> res=new ArrayList<>();
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        Arrays.sort(nums);
        res.clear();
        backTrack(nums,0,new ArrayList<>());
        return res;
    }
    public void backTrack(int[] nums,int curr,ArrayList<Integer> curr_res){
        if (curr>=nums.length){
            res.add(new ArrayList<>(curr_res));
            return;
        }
        // all subsets contain nums[curr]
        curr_res.add(nums[curr]);
        backTrack(nums,curr+1,curr_res);
        curr_res.remove(curr_res.size()-1);
        // all subsets don't contain nums[curr]
        while (curr+1<nums.length&&nums[curr+1]==nums[curr]){
            curr++;
        }
        backTrack(nums,curr+1,curr_res);

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值