【leetcode学习计划】算法入门(14 / 14)完结!

目录

DAY1.二分查找 

704.二分查找

278.第一个错误版本

!35.搜索插入位置

DAY2.双指针

977.有序数组的平方

189.轮转数组

DAY3.双指针

!283.移动零

!167.两数之和 2 - 输入有序数组

DAY4.双指针

557.反转字符串中的单词3

DAY5.双指针

876.链表的中间结点

19.删除链表的倒数第n个结点

DAY6.滑动窗口

3.无重复字符的最长子串

unordered_set

567.字符串的排列

DAY7. DFS/BFS

733.图像渲染

方法一:dfs

方法二:bfs 

695.岛屿的最大面积

方法一:dfs

 方法二:bfs

DAY8.DFS/BFS

617.合并二叉树

!116.填充每个节点的下一个右侧节点指针

DAY9. DFS/BFS

542.01矩阵

994.腐烂的橘子

DAY10.递归/回溯

21.合并两个有序链表

206.反转链表

DAY11.递归/回溯

77.组合

46.全排列

784.字母大小写全排列

DAY12.动态规划

70.爬楼梯

198.打家劫舍

120.三角形最小路径和

DAY13.位运算

231.2的幂

191.位1的个数

 Integer.bitCount(n) 返回1的个数

DAY14.位运算

190.颠倒二进制位

 Integer.reverse(n); 反转

136.只出现一次的数字


DAY1.二分查找 

704.二分查找

力扣

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int l=0,r=nums.size()-1;
        while(l<r)
        {
            int mid=l+r>>1;
            if(nums[mid]>=target) r=mid;
            else l=mid+1;
        }
        if(nums[l]!=target) return -1;
        else return l;
    }
};

278.第一个错误版本

力扣

直接mid = l+r >> 1会溢出,要改变一下,mid=l+(r-l) / 2

class Solution {
public:
    int firstBadVersion(int n) {
        int l=1,r=n;
        while(l<r)
        {
            int mid=l+(r-l)/2;
            if(isBadVersion(mid)==true) r=mid;
            else l=mid+1;
        }
        return l;
    }
};

!35.搜索插入位置

力扣

需要加个特判,如果这个数比最终查找位置大,返回位置应该+1

如果比最终位置小,直接返回该数下标即可

例如:1 3 5 6  插入0  输出:0

           1 3 5 6  插入7  输出:4

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int l=0,r=nums.size()-1;
        while(l<r)
        {
            int mid=l+r+1>>1;
            if(nums[mid]<=target) l=mid;
            else r=mid-1;
        }
        if(nums[l]<target) return l+1;
        return l;
    }
};

DAY2.双指针

977.有序数组的平方

力扣

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        int n=nums.size();
        int l=0,r=n-1;
        int cnt=n-1;
        vector<int>res(n);
        while(l<=r)
        {
            if(nums[l]*nums[l]>nums[r]*nums[r]) 
                res[cnt--]=nums[l]*nums[l],l++;
            else res[cnt--]=nums[r]*nums[r],r--;
        }
        return res;
    }
};

189.轮转数组

力扣

直接定位法

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        int n=nums.size();
        vector<int>res(n);
        for(int i=0;i<n;i++) 
            res[(i+k)%n]=nums[i]; 
        nums=res;
    }
};

翻转数组法

例如:1 2 3 4 5

第一步先翻转整个数组 5 4 3 2 1

第二步按k划分 5 4 3    2 1

第三步各自翻转 3 4 5 1 2 

class Solution {
public:
    void reverse(vector<int>& nums,int l,int r)
    {
        while(l<r)
        {
            swap(nums[l],nums[r]);
            l++;
            r--;
        }
    }

    void rotate(vector<int>& nums, int k) {
        int n=nums.size();
        k%=n;
        reverse(nums,0,n-1);
        reverse(nums,0,k-1);
        reverse(nums,k,n-1);
    }
};

DAY3.双指针

!283.移动零

力扣

左指针指向为0的数

右指针指向不为0的数

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int n=nums.size();
        int l=0,r=0;
        while(r<n)
        {
            if(nums[r]) swap(nums[l],nums[r]),l++;
            r++;
        }   
    }
};

!167.两数之和 2 - 输入有序数组

力扣

双指针法

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        int n=numbers.size();
        int l=0,r=n-1;
        while(l<r)
        {
            if(numbers[l]+numbers[r]>target) r--;
            else if(numbers[l]+numbers[r]<target) l++;
            else return{l+1,r+1};
        }
        return {-1,-1};
    }
};

二分法 

可以先固定一个数i,再利用二分,在比i大的区间里找另一个数满足n[i]+n[l]==target

class Solution {
public:
    vector<int> twoSum(vector<int>& numbers, int target) {
        int n=numbers.size();
        for(int i=0;i<n;i++)
        {
            int l=i+1,r=n-1;
            while(l<r)
            {
                int mid=l+r>>1;
                if(numbers[i]+numbers[mid]>=target) r=mid;
                else l=mid+1;
            }
            if(numbers[i]+numbers[r]==target) return{i+1,r+1};
        }
        return {-1,-1};
    }
};

DAY4.双指针

557.反转字符串中的单词3

力扣

双指针法

class Solution {
public:
    string reverseWords(string s) {
        int n=s.size();
        int l=0,r;
        for(int i=0;i<=n;i++)
            if(s[i]==' '||s[i]=='\0')
            {
                for(r=i-1;r>l;r--,l++) swap(s[l],s[r]);
                l=i+1;
            }
        return s;
    }
};

class Solution {
public:
    string reverseWords(string s) {
        stringstream ss(s);
        string str;
        string res;
        bool f=false;
        while(ss>>str)
        {
            reverse(str.begin(),str.end());
            if(f)res+=" ";
            f=true;
            res+=str;
        }
        return res;
    }
};

DAY5.双指针

876.链表的中间结点

力扣

暴力遍历

先求链表长度 再找len/2的位置

class Solution {
public:
    ListNode* middleNode(ListNode* head) {
        int len=0;
        ListNode *t=head;
        while(t!=NULL)
        {
            len++;
            t=t->next;
        }
        int i=0;
        while(i<len/2)
        {
            head=head->next;
            i++;
        }
        return head;
    }
};

快慢指针

快指针一次走两步 慢指针一次走一步

当快指针走到末尾时 慢指针恰好走到中间位置 

  • 奇数情况:如1 2 3 4 5 当慢指针在中点3时,快指针在5位置,即high->next=NULL
  • 偶数情况:如1 2 3 4 5 6 当慢指针在4时,快指针在6的后一位置,即high=NULL

如果high指针满足以上两个条件的任意一个,则不需要移动指针,而返回慢指针

class Solution {
public:
    ListNode* middleNode(ListNode* head) {
        ListNode *slow=head,*high=head;
        while(high!=NULL&&high->next!=NULL) 
        {
            high=high->next->next;
            slow=slow->next;
        }
        return slow;
    }
};

19.删除链表的倒数第n个结点

力扣

暴力遍历

需要注意特判 链表长度为1 和 删除的是头结点的情况(即len==n)

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        int len=0;
        ListNode *t=head;
        while(t!=NULL)
        {
            t=t->next;
            len++;
        }
        if(len==1||len==n) return head->next; //如果链表只有一个元素则返回NULL 如果要删除头结点 直接返回头结点之后的链表
        ListNode *p=head,*q=NULL;
        for(int i=1;i<len-n;i++) p=p->next;
        q=p->next;
        p->next=q->next;
        return head;
    }
};

快慢指针

快指针先走n个结点 然后快慢指针同时走

当快指针走到末尾时 慢指针恰好指向倒数第n个节点的前驱结点

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        if(head->next==NULL) return head->next; 
        ListNode *high=head,*slow=head;
        for(int i=0;i<n;i++) high=high->next;
        if(!high) return head->next; //如果快指针指出范围 说明要删除的是头结点
        while(high->next)
        {
            high=high->next;
            slow=slow->next;
        }
        slow->next=slow->next->next;
        return head;
    }
};

DAY6.滑动窗口

3.无重复字符的最长子串

力扣

unordered_set

该容器中不包含重复元素

mp.find() 查找对应元素,成功返回对应的迭代器,失败返回最后一个元素迭代器(即 mp.end() )

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(s.size()==0) return 0;
        int maxl=-1,l;
        unordered_set<char>mp;
        for(int i=0;i<s.size();i++)
        {
            while(mp.find(s[i])!=mp.end())//如果在窗口中找到重复元素 则擦除左端 移动窗口
            {
                mp.erase(s[l]);
                l++;
            }
            maxl=max(maxl,i-l+1);
            mp.insert(s[i]);
        }
        return maxl;
    }
};

567.字符串的排列

力扣

class Solution {
public:
    bool checkInclusion(string s1, string s2) {
        if(s1.size()>s2.size()) return false;
        vector<int>v1(26,0);
        vector<int>v2(26,0);
        for(int i=0;i<s1.size();i++) //因为不要求顺序 所以只要统计字母的出现次数就可以
        {
            v1[s1[i]-'a']++;
            v2[s2[i]-'a']++;
        }
        if(v1==v2) return true;

        for(int i=s1.size();i<s2.size();i++)
        {
            v2[s2[i]-'a']++;
            v2[s2[i-s1.size()]-'a']--; //保持窗口长度为s1的长度
            if(v1==v2) return true;
        }
        return false;
    }
};

DAY7. DFS/BFS

733.图像渲染

力扣

方法一:dfs

我们从给定的起点开始,进行深度优先搜索。

每次搜索到一个方格时,如果其与初始位置的方格颜色相同,就将该方格的颜色更新,以防止重复搜索;如果不相同,则进行回溯。

class Solution {
public:
    int dx[4]={0,0,-1,1};
    int dy[4]={1,-1,0,0};

    void dfs(vector<vector<int>>&g,int x,int y,int cur,int color)
    {
        int m=g.size(),n=g[0].size();
        if(g[x][y]==cur)
        {
            g[x][y]=color;
            for(int i=0;i<4;i++)
            {
                int a=x+dx[i],b=y+dy[i];
                if(a<0||a>m-1||b<0||b>n-1) continue;
                dfs(g,a,b,cur,color);
            }
        }
    }
    
    vector<vector<int>> floodFill(vector<vector<int>>& g, int sr, int sc, int color) {
        int cur=g[sr][sc];
        if(cur!=color)
            dfs(g,sr,sc,cur,color);
        return g;
    }
};

方法二:bfs 

我们从给定的起点开始,进行广度优先搜索。

每次搜索到一个方格时,如果其与初始位置的方格颜色相同,就将该方格加入队列,并将该方格的颜色更新,以防止重复入队。

注意:因为初始位置的颜色会被修改,所以我们需要保存初始位置的颜色,以便于之后的更新操作。

typedef pair<int,int> PII;
class Solution {
public:
    int dx[4]={0,0,-1,1};
    int dy[4]={1,-1,0,0};

    void bfs(vector<vector<int>>&g,int x,int y,int cur,int color)
    {
        int m=g.size(),n=g[0].size();
        g[x][y]=color;
        queue<PII>q;
        q.push({x,y});
        while(!q.empty())
        {
            auto t=q.front();
            int a=t.first,b=t.second;
            q.pop();
            for(int i=0;i<4;i++)
            {
                int aa=a+dx[i],bb=b+dy[i];
                if(aa<0||aa>m-1||bb<0||bb>n-1) continue;
                if(g[aa][bb]==cur) g[aa][bb]=color,q.push({aa,bb});
            }
        }
    }
    
    vector<vector<int>> floodFill(vector<vector<int>>& g, int sr, int sc, int color) {
        int cur=g[sr][sc];
        if(cur!=color)
            bfs(g,sr,sc,cur,color);
        return g;
    }
};

695.岛屿的最大面积

力扣

方法一:dfs

class Solution {
public:
    int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};

    int dfs(vector<vector<int>>&g,int x,int y)
    {
        int m=g.size(),n=g[0].size();
        if(x<0||x>m-1||y<0||y>n-1) return 0;
        if(g[x][y]==0) return 0;
        g[x][y]=0;
        int res=1;
        for(int i=0;i<4;i++)
        {
            int a=x+dx[i],b=y+dy[i];
            res+=dfs(g,a,b);
        }
        return res;
    }

    int maxAreaOfIsland(vector<vector<int>>& g) {
        int m=g.size(),n=g[0].size();
        int res=0;
        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++)
                res=max(res,dfs(g,i,j));
        return res;
    }
};

 方法二:bfs

typedef pair<int,int> PII;
class Solution {
public:
    int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};

    int bfs(vector<vector<int>>&g,int x,int y)
    {
        int m=g.size(),n=g[0].size();
        queue<PII>q;
        q.push({x,y});
        g[x][y]=0;
        int res=1;
        while(!q.empty())
        {
            auto t=q.front();
            q.pop();
            int a=t.first,b=t.second;
            for(int i=0;i<4;i++)
            {
                int aa=a+dx[i],bb=b+dy[i];
                if(aa<0||aa>m-1||bb<0||bb>n-1) continue;
                if(g[aa][bb]==1) q.push({aa,bb}),res++,g[aa][bb]=0;
            }
        }
        return res;
    }

    int maxAreaOfIsland(vector<vector<int>>& g) {
        int m=g.size(),n=g[0].size();
        int res=0;
        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++)
                if(g[i][j]==1)
                    res=max(res,bfs(g,i,j));
        return res;
    }
};

DAY8.DFS/BFS

617.合并二叉树

力扣

class Solution {
    public TreeNode mergeTrees(TreeNode t1, TreeNode t2) {
        if(t1==null) return t2;
        if(t2==null) return t1;

        //如果都存在结点 则创建一个新结点储存两个结点值之和
        TreeNode newroot=new TreeNode(t1.val+t2.val);
        //递归合并左子树
        newroot.left=mergeTrees(t1.left,t2.left);
        //递归合并右子树
        newroot.right=mergeTrees(t1.right,t2.right);

        return newroot;
    }
}

!116.填充每个节点的下一个右侧节点指针

力扣

  • 如果结点为NULL或者左右子树均为NULL:没有需要做的,直接返回结点本身。
  • 对于左右子树均存在的结点:
  • 首先左子树的next一定不会指向NULL,直接设置指向右子树即可;
  • 对于右子树,他的next是要指向父结点右兄弟的左子树的,可以通过root->next->left找到这个结点,但只有一种情况下例外,就是父结点没有右兄弟(root->next == NULL)
class Solution {
    public Node connect(Node root) {
        if(root==null||root.left==null) return root;
        root.left.next=root.right; //左子树的next肯定不为空 直接指向右子树
        if(root.next!=null) //如果父结点有右兄弟
            root.right.next=root.next.left;//指向父节点右兄弟的左子树
        connect(root.left);
        connect(root.right);
        return root;
    }
}

DAY9. DFS/BFS

542.01矩阵

542. 01 矩阵

bfs:

首先把每个源点 0入队,然后从各个 0 同时开始一圈一圈的向 1 扩散(每个 1 都是被离它最近的 0 扩散到的 )

class Solution {
    public int[][] updateMatrix(int[][] g) {
        int m=g.length,n=g[0].length;
        Queue<int[]> q=new LinkedList<>();
        //将所有0入队,并将1的位置设成-1 标记为未访问
        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++)
                if(g[i][j]==0) q.offer(new int[] {i,j});
                else g[i][j]=-1;

        int[] dx=new int[]{0,0,-1,1},dy=new int[]{1,-1,0,0};
        while(!q.isEmpty())
        {
            int[] t=q.poll();
            int x=t[0],y=t[1];
            for(int i=0;i<4;i++)
            {
                int a=dx[i]+x,b=dy[i]+y;
                if(a>=0&&a<m&&b>=0&&b<n&&g[a][b]==-1)
                {
                    g[a][b]=g[x][y]+1;
                    q.offer(new int[] {a,b});
                }
            }
        }
        return g;
    }
}

994.腐烂的橘子

994. 腐烂的橘子

bfs:

让腐烂的橘子入队 遍历第一次腐烂的橘子 逐一感染

class Solution {
    public int orangesRotting(int[][] g) {
        int m=g.length,n=g[0].length;
        int res=0;
        Queue<int[]> q=new LinkedList<>();
        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++)
                if(g[i][j]==2) q.offer(new int[] {i,j});

        int[] dx=new int[]{0,0,1,-1},dy=new int[]{1,-1,0,0};
        while(!q.isEmpty())
        {
            int num=q.size();//统计本轮腐烂橘子的个数
            for(int i=0;i<num;i++)
            {
                int[] t=q.poll();
                int x=t[0],y=t[1];
                for(int j=0;j<4;j++)
                {
                    int a=dx[j]+x,b=dy[j]+y;
                    if(a<0||a>=m||b<0||b>=n) continue;
                    if(g[a][b]==1)
                    {
                        g[a][b]=2;
                        q.offer(new int[] {a,b});
                    } 
                }
            }
            if(!q.isEmpty()) res++;//如果一开始就感染完了 res=0
        }
        //检查还有没有新鲜橘子
        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++)
                if(g[i][j]==1) return -1;
        return res;
    }
}

DAY10.递归/回溯

21.合并两个有序链表

力扣

class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode head=new ListNode(-1);
        ListNode p=head;
        while(l1!=null&&l2!=null)
        {
            if(l1.val>l2.val)
            {
                p.next=l2;
                l2=l2.next;
            }else{
                p.next=l1;
                l1=l1.next;
            }
            p=p.next;
        }
        p.next= l1==null?l2:l1;
        return head.next;
    }
}

206.反转链表

力扣

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode p=null;
        ListNode cur=head;
        while(cur!=null)
        {
            ListNode t=cur.next;
            cur.next=p;
            p=cur;
            cur=t;
        }
        return p;
    }
}
class Solution {
    public ListNode reverseList(ListNode head) {
        if(head==null||head.next==null) return head;
        ListNode cur=reverseList(head.next);
        head.next.next=head;
        head.next=null;
        return cur;
    }
}

DAY11.递归/回溯

77.组合

77. 组合

思路:

关于剪枝:

  • 要组成大小为k的v,此时还需要k - v.size()个数,如果[i, n]这个区间内(有n - i + 1个数)不足这么多,则肯定没有结果,直接剪枝。
  • 因此剪枝条件为:n - i + 1 < k - v.size(),推出来上界为i = n - k + v.size() + 1
class Solution {
    List<List<Integer>> res=new ArrayList<>();
    List<Integer> v=new ArrayList<>();
    public List<List<Integer>> combine(int n, int k) {
        dfs(1,n,k);
        return res;
    }

    public void dfs(int start,int n,int k)
    {
        if(v.size()==k) //如果一组已经存满了 则把结果存入res
        {
            res.add(new ArrayList<>(v));//深拷贝 对象中开辟一个新地址,存放的内容为list链表,所以后续不会被影响
            return;
        }

        for(int i=start;i<=n-k+v.size()+1;i++)
        {
            v.add(i);
            dfs(i+1,n,k);
            v.remove(v.size()-1);//回溯操作(回退处理结点[1, 2] 撤销2 ,[1, 3] 撤销3),然后继续遍历
        }
    }
}

46.全排列

46. 全排列

思路:

class Solution {
    List<List<Integer>> res = new ArrayList<>();
    List<Integer> v=new ArrayList<>();

    public List<List<Integer>> permute(int[] nums) {

        int[] visited = new int[nums.length];
        backtrack(nums,visited);
        return res;
    }

    private void backtrack(int[] nums, int[] visited) {
        if(v.size()==nums.length) {
            res.add(new ArrayList<>(v));
            return;
        }
        for(int i=0;i<nums.length;i++) 
        {
            if(visited[i]==1) continue;
            v.add(nums[i]);
            visited[i]=1;
            backtrack(nums,visited);
            visited[i]=0;
            v.remove(v.size()-1);
        }
    }
}

784.字母大小写全排列

784. 字母大小写全排列

class Solution {
    List<String> res=new ArrayList<>();

    public List<String> letterCasePermutation(String s) {
        
        char[] ch=s.toCharArray();
        int n=s.length();
        dfs(ch,n,0);
        return res;
    }

    private void dfs(char[] ch,int n,int idx)
    {
        res.add(new String(ch));
        for(int i=idx;i<n;i++)
            if(!Character.isDigit(ch[i]))
            {
                char t=ch[i];
                ch[i]=(char)((ch[i]-'a'>=0)? ch[i]-32:ch[i]+32);
                dfs(ch,n,i+1);
                ch[i]=t; //恢复现场
            }
    }
}

DAY12.动态规划

70.爬楼梯

70. 爬楼梯

本问题其实常规解法可以分成多个子问题,爬第n阶楼梯的方法数量,等于 2 部分之和

  • 爬上 n-1 阶楼梯的方法数量。因为再爬1阶就能到第n阶
  • 爬上 n-2 阶楼梯的方法数量。因为再爬2阶就能到第n阶

所以我们得到公式 dp[n] = dp[n-1] + dp[n-2]
同时需要初始化 dp[0]=1和dp[1]=1

第0阶台阶1种方法 第1阶台阶1种方法 

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

斐波那契数列

其实就是斐波那契数列

1 2 3 5 8…… 

class Solution {
    public int climbStairs(int n) {
        if(n<=2) return n;
        int a=1,b=2,t;
        for(int i=3;i<=n;i++)
        {
            t=a+b;
            a=b;
            b=t;
        }
        return b;
    }
}

198.打家劫舍

198. 打家劫舍

dp[i] 第i间房可盗窃的最大值

因为不可以闯入相邻的房间 所以在第n间房可以盗窃的最大值=

  • 不盗取第n间房,所以盗取第n-1间房  dp[n]=dp[n-1]
  • 盗取第n间房,所以不能盗窃第n-1间房  dp[n]=dp[n-2]+当前房的值num

所以动态规划方程:dp[n] = max( dp[n-1],dp[n-2]+num )

eg:

1号房可盗窃最大值为3        dp[1]=3

2号房可盗窃最大值为4        dp[2]=4

3号房值为2 num=2              dp[3]=max(dp[2],dp[1]+num)=max(4,3+2)=5

class Solution {
    public int rob(int[] nums) {
        int n=nums.length;
        int[] dp=new int[n+1]; //开辟的是0~n的空间
        dp[0]=0;
        dp[1]=nums[0];
        for(int i=2;i<=n;i++)
            dp[i]=Math.max(dp[i-1],dp[i-2]+nums[i-1]);
        return dp[n];
    }
}

120.三角形最小路径和

120. 三角形最小路径和

dp[i][j] 表示从点 (i, j) 到底边的最小路径和

自下而上算

dp[i][j]=min(下一行的左右数值)+自己的值

最后返回顶上的值就是最小路径和

class Solution {
    public int minimumTotal(List<List<Integer>> t) {
        int n=t.size();
        int[][] dp=new int[n+1][n+1];
        for(int i=n-1;i>=0;i--) // 最后一行跳过 从倒数第二行开始算
            for(int j=0;j<=i;j++)
             dp[i][j]=Math.min(dp[i+1][j],dp[i+1][j+1])+t.get(i).get(j);
        return dp[0][0];
    }
}

 

DAY13.位运算

231.2的幂

231. 2 的幂

class Solution {
    public boolean isPowerOfTwo(int n) {
        return n>0 && (n&(n-1))==0;
    }
}

191.位1的个数

191. 位1的个数

public class Solution {
    public int hammingWeight(int n) {
        int res=0;
        while(n!=0)
        {
            n&=n-1;
            res++;
        }
        return res;
    }
}

 Integer.bitCount(n) 返回1的个数

public class Solution {
    public int hammingWeight(int n) {
        return Integer.bitCount(n);
    }
}

DAY14.位运算

190.颠倒二进制位

190. 颠倒二进制位

public class Solution {
    public int reverseBits(int n) {
        int res=0;
        for(int i=0;i<32;i++)
        {
            int t=n&1; //获取最后的数字
            n>>=1;
            res<<=1; //结果数字左移,为新到来的数字腾出空间
            res|=t; //或运算,将新到来的数字加到原来的数字上
        }
        return res;
    }
}

 Integer.reverse(n); 反转

public class Solution {
    public int reverseBits(int n) {
        return Integer.reverse(n);
    }
}

136.只出现一次的数字

 136. 只出现一次的数字

class Solution {
    public int singleNumber(int[] a) {
        int res=0;
        for(int x:a) res^=x;
        return res;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值