20220115剑指offer刷题

剑指 Offer II 012. 左右两边子数组的和相等

题目描述:

给你一个整数数组 nums ,请计算数组的 中心下标 。

数组 中心下标 是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。

如果中心下标位于数组最左端,那么左侧数之和视为 0 ,因为在下标的左侧不存在元素。这一点对于中心下标位于数组最右端同样适用。

如果数组有多个中心下标,应该返回 最靠近左边 的那一个。如果数组不存在中心下标,返回 -1 。

分析:左侧数的和和右侧数的和要一样,都等于总和的一半 代码如下:

public class Solution {
    public int PivotIndex(int[] nums) {
       int total = nums.Sum();           //求数组的总和
       int sum = 0; 
       for(int i = 0;i<nums.Length;i++){ 
           if(sum*2+nums[i]==total){      
               return i;
           }
           sum += nums[i];
       }
       return -1;
    }
}
  • 本题要重点记住的是C#中数组的求和语句 nums.Sum()

最终结果:

 剑指 Offer II 005. 单词长度的最大乘积

题目描述:

给定一个字符串数组 words,请计算当两个字符串 words[i] 和 words[j] 不包含相同字符时,它们长度的乘积的最大值。假设字符串中只包含英语的小写字母。如果没有不包含相同字符的一对字符串,返回 0。

分析:

首先要明确一点,本题肯定是要每个字符串都两两比较一下的,这是不可避免的,可以减少的操作就是对于一个字符串来说,重复的字符就不要考虑了 

因为只有小写字符,所以包含的字符最多就是26个。所以每一个字符串都可以通过一个26位的2进制码来表示该字符串是否包含该字符。

例如:‘ab’就可以表示成0001|0010=0011 ‘cd’可以表示成0100|1000=1100    'ab'和'cd'没有相同的字符,将它们的二进制码作与操作,可以得到0011&1100 = 0000=0  如果是‘ab’和‘a’,那么0011&0001=0001=1!=0,所以‘ab’和‘a’有相同的字符

然后将字符串们的2进制码两两作与操作,若最后结果是0,说明两个字符串没有相同的字符

知识积累:与操作结果为0,可以用来作为判断两者是否要相同部分的有效方法(灵活运用位操作作为标识符

代码如下:

public class Solution {
    public int MaxProduct(string[] words) {
        var MaskArray = new int[words.Length]; //存储每个字符串的二进制码
        int MaxLength = 0;
        for(int i = 0;i<words.Length;i++){
            MaskArray[i] = CharToArray(words[i]);
        }
        for(int i =0;i<MaskArray.Length;i++){
            for(int j =i+1;j<MaskArray.Length;j++){
                if((MaskArray[i] & MaskArray[j])==0){
                    MaxLength = Math.Max(MaxLength,words[i].Length*words[j].Length);
                }
            }
        }
        return MaxLength;
    }
    //设置一个函数实现将字符串变成二进制码
    int CharToArray(string word){
        int res = 0;
        foreach(var item in word){
            res |= (1<<(item - 'a')); //位操作,左移
        }
        return res;
    }
}

最后结果也很好:

  • 总结1:灵活运用位操作和位运算,可以解决很多难解的问题,提高问题解决的效率
  • 总结2:涉及到只有大写/小写字母的,都要想到最多有26种情况,最不济可以用一个长度位6的数组来存储记录
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值