发散思维
-
程序员是一个高危职业,最近动不动就听到谁谁谁猝死,谁谁谁过劳晕倒,所以面对奇葩问题,我们要淡定,
-
开发中被产品虐,说的最多的一句话就是这个需求很简单,怎么实现我不管
-
找工作被面试官虐,你不能用这个,不能用哪个,还得给我答案
-
最近碰到了这种奇葩的题目:
-
第一眼看这种问题,心里一万头草泥马鹏腾而过,陷入沉默中,我表示很慌
- 这种问题一看就不按常理出牌,不能用常规思路去应对,要不然会被气死,这也是发散思维的重要吧(我觉得就是脑筋急转弯),也许是为了考察你心态,不能轻言放弃
- 我们还是来分析一下这个问题吧:
- 四则运算不能用,那还能用啥,能想到的只有位运算了吧,总不可能取余,取模运算能搞定加法吧
- 二进制只有 与, 或,非,异或,没思路,还是从十进制开始分析吧
- 例如24 + 19 =43,加法,各个位数相加,得到对应的位数的值,有进位则将进位添加到高位去
- 总的来说就两步:
- 第一步做加法 得到 33
- 第二步做进位9+4 有进位 10, 所以33 + 10 = 43
- 同理是否可以运用到二进制中呢,我们用二进制也做如下分析:
- 如上图,如果我们用这种方式 标识:
- 24 : 0001 1000 , 19: 0001 0011, 相加后得到 0010 1011 与结果相符,因为二进制中并没有这么相加的
- 但是二模拟加法的话并没有一个操作符完成,那么还按以上步骤进行:
- 先做加法,在做进位,加法怎么实现, 二进制中 0+1 = 1 ,1+0 =1 ,0+0=0, 1+1 =0, 和异或居然是一样的,那么我们可以通过 num1 ^ num2 得到相加的结果
-
因为只有都是1 的位数才有进位,并且在高位相加,找到都是1 的位,我们在之前的位运算文中提到过,用与操作,剩下的就都是1 的位数 1 ^ 1 = 1, 在左移就将1 移动到高位,num1 & num2 << 1
-
那么我们只要将这两个在相加 (num1 ^ num2) + (num1 & num2 << 1),就得到最终结果
-
那么加法又回到了第一个步骤
-
经过如上分析,很显然是一个递归或者循环 位运算的问题,那么就能通过位运算得到 加法的解法了
-
遇到这种问题还是要稳住,不要慌,那么我们有如下实现:
/*** @author liaojiamin* @Date:Created in 16:39 2021/7/8*/
public class SummationForBit {public static void main(String[] args) {System.out.println(sumForBit(12,13));}/*** 利用位运算做加法** */public static int sumForBit(int num1, int num2){int sum = 0;int curry = 0;do{sum = num1 ^ num2;curry = (num1 & num2)<<1;num1 = sum;num2 = curry;}while (curry != 0);return sum;}
}
发散思维二
-
求1+2+3+…+n要求不能用乘法,除法,for,while,if,else,switch,case,以及调节判断语句;
-
卧槽不就是不能写所有逻辑还要求解吗,能用的逻辑操作都给你禁了还要求和。一般我们求等差数列,一般都是用公式(n+1)*n/2,或者循环,或者递归,但是封死了if, for, while,递归循环都不行了,你递归总得有终止条件吧
-
这是何等的卧槽,那么还是有办法的,不让用循环,那就只能写n次加法了,还不能用逻辑操作,那么就必须定义实例就执行逻辑,就是构造方法了
-
通过构造方法执行逻辑,然后构造n次,得到结果
/*** @author liaojiamin* @Date:Created in 14:49 2021/7/8*/
public class Summation {private static int sum;public void setNumber(int result){sum = result;}public Summation(int result, int number){setNumber(result);sum+=number;}public int getNumber(){return sum;}public static void main(String[] args) {int s1 = new Summation(0,1).getNumber();int s2 = new Summation(s1,2).getNumber();int s3 = new Summation(s2,3).getNumber();int s4 = new Summation(s3,4).getNumber();int s5 = new Summation(s4,5).getNumber();int s6 = new Summation(s5,6).getNumber();int s7 = new Summation(s6,7).getNumber();int s8 = new Summation(s7,8).getNumber();int s9 = new Summation(s8,9).getNumber();int s10 = new Summation(s9,10).getNumber();int s11 = new Summation(s10,11).getNumber();System.out.println(s7);}
}
- 这个犯法太蠢了,蠢哭了,上面通过不断定义新对象来调用构造方法来实现累加,下面来一个递归的恶心写法
/*** @author liaojiamin* @Date:Created in 15:16 2021/7/8*/
public enum SummationRecursion {LAST_4(4){@Overridepublic int mySumResult(){return this.getSummation() + LAST_3.mySumResult();}},LAST_3(3){@Overridepublic int mySumResult(){return this.getSummation() + LAST_2.mySumResult();}},LAST_2(2){@Overridepublic int mySumResult(){return this.getSummation() + LAST_1.mySumResult();}},LAST_1(1){@Overridepublic int mySumResult(){return 1;}};private int summation;public int getSummation() {return summation;}public void setSummation(int summation) {this.summation = summation;}SummationRecursion(int summation){this.summation = summation;}public abstract int mySumResult();public static void main(String[] args) {System.out.println(SummationRecursion.LAST_4.mySumResult());}
}
-
利用枚举中的抽象方法,每个抽象方法都调用下个层级的抽象方法,最终的跳出条件是 LAST_1 的抽象方法直接返回的1,类似一个递归的操作来求解。
-
我看了这种代码都想吐,居然是自己写的。
-
以上这些问题,都是提醒我们,当被限制的无以复加的时候,感觉啥都不能做了,我们应该发挥脑筋急转弯的创造力,打开新的思路,不要怂就是干,这就是发散思维的精髓。
上一篇:数据结构与算法–我们来玩丢手绢(约瑟夫环问题)
下一篇:数据结构与算法–死磕二叉树