极客03练习题目笔记

一些小结:勉励自己
1.从计划刷题以来,出现了一些方法策略的错误,在朋友的帮助下,慢慢回到正轨,效率up 开心up
2.代码写完要向优秀代码学习,对自己的代码进行优化,比如格式,判断语句如何写更精炼
3.判断,循环类语句注意空格 例:for 🈳️(....)
4.加油,没有翻不过的大山,没有什么是战胜不了的,坚持,成为一种习惯

283.移动零easy

class Solution {
    public void moveZeroes(int[] nums) {
        

        int j = 0;
        for(int i = 0;i < nums.length;++i){
            if(nums[i] != 0){
                nums[j] = nums[i];
                if (i != j){
                    nums[i] = 0;
                }
                j++;
            }
            
        }
    }
}

11.盛水最多的容器medium

【way 1】嵌套循环遍历

class Solution {
    public int maxArea(int[] height) {
            int max = 0;
            for (int i = 0; i < height.length - 1; ++i){
                for (int j = i + 1; j < height.length; ++j){
                    //int area = _getArea(i,j);
                    int area = (j - i) * Math.min(height[i], height[j]);
                    max = Math.max(max, area);

                }
            }
        
        return max;
    }
}

【way 2】左右边界,向中间收敛,O(n)
简称:左右夹逼

class Solution {
    public int maxArea(int[] a) {
        int max = 0;
        for(int i = 0,j = a.length - 1;i < j;){
            int minHeight = a[i] < a[j] ? a[i ++] : a[j --];
            int area = (j - i + 1) * minHeight;
            max = Math.max(max, area);
        }
        return max;
    }
}

70爬楼梯 easy

思想:最近重复子问题
1:1
2:2
3:f(1) + f(2)
4:f(2) + f(3)
:
n:f(n-1)+f(n-2)
本质:Fibonacci数列

class Solution(object):
    def climbStairs(self, n):
        if(n <= 2): return n
        f1,f2,f3 = 1, 2, 3
        for i in range(3, n+1):
            f3 = f1 + f2
            f1 = f2
            f2 = f3
        return f3
      

1 两数之和easy

class Solution {
    public int[] twoSum(int[] nums, int target) {
        for(int i = 0;i < nums.length;i++){
            for(int j = i+1;j < nums.length;j++){
                if(nums[j] == target - nums[i]){
                    return new int[]{i,j};
                }
            }
        }
        throw new IllegalArgumentException("No two sum solution");
    }
}
class Solution {
    public int[] twoSum(int[] nums, int target) {
        int[] a = new int[2];
        int numsSize = nums.length;
        for(int i = 0;i < numsSize - 1;i++){
            for(int j = i + 1;j < numsSize;j++){
                if(nums[i] + nums[j] == target){
                    a[0] = i;
                    a[1] = j;
                    return a;
                }

            }
        }
        return new int[0];
        
    }
}

15 三数之和-med-高频老题

双指针法-首先排序
空间复杂度 O(1):指针使用常数大小的额外空间

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        //a + b = -c
        //1.暴力求解O(n ^ 3)
        //2.hash表
        //3.双指针,左右下标往中间推进
        Arrays.sort(nums);//排序
        List<List<Integer>> res = new ArrayList<>();
        for(int k =0; k < nums.length - 2; k++){
            if(nums[k] > 0) break;
            if(k > 0 && nums[k] == nums[k - 1]) continue;
            int i = k + 1, j = nums.length - 1;
            while(i < j){
                int sum = nums[i] + nums[j] + nums[k];
                if(sum < 0){
                    while(i < j && nums[i] == nums[++i]);
                }
                else if(sum > 0){
                    while(i < j && nums[j] == nums[--j]);
                }
                else{
                    res.add(new ArrayList<Integer>(Arrays.asList(nums[k], nums[i], nums[j])));
                    while(i < j && nums[i] == nums[++i]);
                    /*while(i < j){
                        i = i + 1;
                        if(nums[i -1] == nums[i]){
                            //do sth
                        }
                    }*/
                    while(i < j && nums[j] == nums[--j]);
                }
            }
        }
        return res;
    }
}

141.环形链表easy

class Solution {
public:
    bool hasCycle(ListNode *head) {
        //int pos = -1;
        //快慢指针,也可用哈希表(目前未实现)
        ListNode* slow = head;
        ListNode*  fast= head;
         if(!head || !head->next) return nullptr;
        while(fast && fast -> next ){
            slow = slow -> next;
            fast = fast -> next -> next;
            if(fast == slow){
                return true;
            }
        }

      return false;  
    }
};

142.环形链表2 MED

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode* fast = head;
        ListNode* slow = head;
        while(fast != NULL && fast -> next != NULL){
            slow = slow -> next;
            fast = fast -> next -> next;
            //快慢指针相遇,确认环的入口点,思路还需再思考
            if(slow == fast){
                ListNode* index1 = fast;
                ListNode* index2 = head;
                while(index1 != index2){
                    index1 = index1 -> next;
                    index2 = index2 -> next;
                }
                return index2;
            }
        }
        return NULL;   
    }
};

25.K个一组翻转链表-hard

【way1 原地翻转】

class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        //原地翻转链表
        ListNode* dummyhead = new ListNode(-1);
        dummyhead -> next = head;
        ListNode* starts = head;//记录移动的后面一个指针
        ListNode* ends = head;//每次需要翻转的第k个指针
        ListNode* pre = dummyhead;//记录当前的头指针
        ListNode* nexts,*cur;//cur 记录当前要移动的指针
        //链表翻转
        while(1){
            for (int i = 0; i < k - 1; i++){
                if (ends == NULL){
                    break;
                }
            
            ends = ends -> next;
        }
        if(ends == NULL){
            break;
        }
        nexts = ends -> next;
        //原地翻转
        for(int i = 0; i < k - 1;i ++){
            cur = starts;
            starts = starts -> next;

            pre -> next = starts;
            cur -> next = ends -> next;
            ends -> next = cur;
        }
        starts = nexts;
        ends = nexts;
        for(int i = 0; i < k;i++){
            pre = pre -> next;
        }  
        
    }
    return dummyhead -> next;
}
};

【way2 头插法】

class Solution {
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode* dummynode = new ListNode(-1);
        ListNode* current = head;
        ListNode* starts = head;
        ListNode* nexts = starts -> next;
        ListNode* pre = dummynode;
        pre -> next = NULL;
        while(1){
            for(int i = 0;i < k -1; i++){
                if(current == NULL){
                    break;
                }
                current = current -> next;
            }
            if(current == NULL){
                break;
            }
            for(int i = 0; i < k; i++){
                nexts = starts -> next;
                starts -> next = pre -> next;
                pre -> next = starts;
                starts = nexts;
            }
            //头插前k个指针
            for(int i = 0; i < k;i++){
                pre = pre -> next;
            }
            current = nexts;
        
        }
        while(starts){
            pre -> next = starts;
            pre = pre -> next;
            starts = starts -> next;
        }
        pre -> next = NULL;
        return dummynode -> next;


        
    }
};

21.合并两个有序链表

【way 1 递归】

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        //注意题意,l1 和 l2 都是升序的
        if(l1 == nullptr ){
            return l2;
        } else if (l2 == nullptr){
            return l1;
        } else if(l1 -> val < l2 -> val ){
            l1 -> next = mergeTwoLists(l1 -> next,l2);
            return l1;
        } else{
            l2 -> next = mergeTwoLists(l1,l2 -> next);
            return l2;
        } 
    } 
    
};

【way 2 迭代】


public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        //迭代
        ListNode* preHead = new ListNode(-1);//哨兵节点
        ListNode* prev = preHead;//全程借助prev 不断调整prev指针的next

        while (l1 != nullptr && l2 != nullptr){
            if (l1 -> val < l2 -> val){
                prev -> next = l1;
                l1 = l1 -> next;
            } else {
                prev -> next = l2;
                l2 = l2 -> next;
            }
            prev = prev -> next;  
        }
        //合并剩余的
        prev -> next = l1 == nullptr ? l2 : l1;
        return preHead -> next; 
    }
};

88.合并两个有序数组Easy🤔

class Solution {
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        int i = nums1.size() - 1;
        m --;
        n --;
        while(n >= 0){
            while (m >= 0 && nums1[m] > nums2[n]){
                swap(nums1[i --],nums1[m --]);
            }
            swap(nums1[i--],nums2[n--]);
        }    
    }
};
二叉树遍历思路-递归方法,未主动维护一个栈
使用一个存放结果的动态数组res 存放结果
子函数实现递归调用

94.二叉树的中序遍历

class Solution {
public:
//递归,未主动维护一个栈
    void mid_order(TreeNode* root,vector<int>& res){
        if(root == NULL){
            return;
        }
        mid_order(root -> left,res);
        res.push_back(root -> val);
        mid_order(root -> right,res);
    }
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        if(!root) return res;
        mid_order(root,res);
        return res;

        
    }
};

144.二叉树的前序遍历

class Solution {
public:
    void pre_order(TreeNode* root,vector<int>& res){
        if(root == NULL) return;
        res.push_back(root -> val);
        pre_order(root -> left,res);
        pre_order(root -> right,res);
    }
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> res;
        if(!root) return res;
        pre_order(root,res);
        return res;

    }
};

590.n叉树的后序遍历

class Solution {
public:
    vector<int> res;
    void order(Node* root){
        Node* tmp;
        for(int i = 0;i < root -> children.size();i++){
            tmp = root -> children[i];
            order(tmp);
        }
        res.push_back(root -> val);
    }
    vector<int> postorder(Node* root) {
        //vector<int> res;
        if(!root) return res;
        order(root);
        return res;
        
    }
};

589.n叉树的前序遍历

class Solution {
public:
    vector<int> res;
    void order(Node* root){
        Node* tmp;
        res.push_back(root -> val);
        for(int i = 0;i < root -> children.size();i++){
            tmp = root -> children[i];
            order(tmp);
        }
    }

    vector<int> preorder(Node* root) {
        if(!root) return res;
        order(root);
        return res;
        
    }
};

70.爬楼梯

#找 最近 重复子问题

#if else
# for while recursion
#只有两种可能性:走一步或者走两步
#1: 1
#2: 2
#3: f(1+ f(2),mutual exclusive,complete exhaustive
#4: f(2+ f(3#f(n) = f(n-1) + f(n-2):Fibonnacci
class Solution(object):
    def climbStairs(self, n):
        if(n <= 2): return n
        f1,f2,f3 = 1, 2, 3
        for i in range(3, n+1):
            f3 = f1 + f2
            f1 = f2
            f2 = f3
        return f3

22.括号生成

class Solution {
    private List<String> result;

    public List<String> generateParenthesis(int n) {
        result = new ArrayList<String>();
        _generate(0, 0, n, "");
        return result;
    }
    private void _generate(int left, int right, int n, String s) {//java 不要用太多的大写
        //terminator
        if ( left == n && right == n){
            System.out.println(s);
            result.add(s);
            return ;
        }
        /*if (level >= max) {
            //filter the invalid   
            // left: 随时加,只要超标 right 必须之前有左括号,且左括号> 右括号
            System.out.println(s);
            return;
        }*/
        //process current logic:left, right
        /*代码优化
        String s1 = s + "(";
        String s2 = s + ")";
        */


        //drill down
        if(left < n){
            _generate(left + 1,right, n, s + "(");

        }
        if(left > right ){
            _generate(left, right + 1, n, s + ")");
        }
        //_generate(level + 1,max, s + "(";
        //_generate(level + 1,max, s + "(");

        //reverse states 

    }

    
}

50.Pow(x , n)

class Solution {
public:
    double subproblem(double x, long long  n){
        if(n == 0) return 1;
        if(n == 1) return x;
        double subresult = subproblem(x, n / 2);

        if(n % 2 == 1) {
            return subresult * subresult * x;
        }else{
            return subresult * subresult;
        }
        

    }
    double myPow(double x, int n) {
        long long N = n;
        if (N < 0){
            x = 1 / x;
            N = - N;
        }
        return subproblem(x ,N);

    }
    
};
//听课思路记录
 /*
        1.暴力
        result = 1
        for i: 0 -> n{
            result *= x
        }
        O(n)
        */

        //2.牛顿迭代法,难

        /*3.分治:转换成子问题
        template:1.terminator 2.process(spilt your big problem) 3.drill down(subproblems,merge(subresult))4.reverse states
        x^n --> 2^10 : 2^5 -> (2^2)*2

        pow(x,n):
            subproblems: subresult = pow(x,n/2)
        log(N)

        merge:
            if(n % 2 == 1){
                // odd
                result = subresult * subresult * x;
            }else{
                // even
                result = subresult * subresult;

            }
        */

78.子集

class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> ans = new ArrayList<>();

        if(nums == null) { return ans; }
        dfs(ans, nums, new ArrayList<Integer>(), 0);
        return ans;
    }
    private void dfs(List<List<Integer>> ans, int[] nums, List<Integer> list, int index) {
        // terminator 终结者
        if (index == nums.length) {
            ans.add(new ArrayList<Integer>(list));
            return;
        }

        dfs(ans, nums, list, index + 1);//not pick the number at this index

        list.add(nums[index]);
        dfs(ans, nums, list, index + 1);// pick the number at this index

        // reverse the current state
        list.remove(list.size() - 1);
    }
} 

【python】

class Solution(object):
    def subsets(self, nums):
        """
        迭代法
        """
        subsets = [[]]

        for num in nums:
            newsets = [];
            for subset in subsets:
                new_subset = subset + [num]
                newsets.append(new_subset)
            subsets.extend(newsets);

        return subsets

【python3】

class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        res = [[]];
        for i in nums:
            res = res + [[i] + num for num in res]简写,掌握
        return res
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值