耗子叔ARTS:第九周

 

Algorithm:

 

/**

 * 19. Remove Nth Node From End of List

 Medium



 1781



 134



 Favorite



 Share

 Given a linked list, remove the n-th node from the end of list and return its head.



 Example:



 Given linked list: 1->2->3->4->5, and n = 2.



 After removing the second node from the end, the linked list becomes 1->2->3->5.

 Note:



 Given n will always be valid.



 Follow up:



 Could you do this in one pass?

 */

/**

 * Definition for singly-linked list.

 * public class ListNode {

 * int val;

 * ListNode next;

 * ListNode(int x) { val = x; }

 * }

 */

 

JAVA:

class ListNode {

    int val;

    ListNode next;



    ListNode(int x) {

        val = x;

        next = null;

    }

}



public ListNode removeNthFromEnd(ListNode head, int n) {

    ListNode node1 = head;

    ListNode node2 = head;

    ListNode node3 = null;

    if (head.next == null) {

        return null;

    }

    for (int i = 0; i < n; i++) {

        node1 = node1.next;

    }

    if (node1 == null) {

        return head.next;

    }

    while (node1.next != null) {

        node2 = node2.next;

        node1 = node1.next;

    }

    node3 = node2.next;

    node2.next = node3.next;

    return head;

}
 

GO:

func removeNthFromEnd(head *ListNode, n int) *ListNode {

   node1 := head

   node2 := head

   node3 := head

   if head.Next == nil {

      return nil

   }

   for i := 0; i < n; i++ {

      node1 = node1.Next

   }

   if node1 == nil {

      return head.Next

   }

   for node1.Next != nil {

      node2, node1 = node2.Next, node1.Next

   }

   node3 = node2.Next

   node2.Next = node3.Next

   //node3, node2.Next = node2.Next, node3.Next

   return head

}

 

Review:

https://medium.com/free-code-camp/how-to-choose-which-programming-language-you-should-learn-in-2019-60abef241012

How to choose which programming language you should learn in 2019

Ariel CamusFollow

May 3

 

 

Image by Pixabay

 

Thanks to the internet, anyone in the world can access world-class resources to learn how to code for little or no money.

While that’s great for anyone who wants to become a software developer, it also creates a challenge — especially if you’re getting started. Every click leads to a new recommended article, tutorial, or YouTube video to learn from.

I’m familiar with the issue through my work at Microverse, an online coding school that doesn’t charge you anything until you get a job — no matter where you’re from. Many of our full-time students applied after being overwhelmed by the number of resources available to them. They were easily distracted, started learning multiple languages, and never mastered anything.

The best way to not get distracted is to hyper-focus on mastering one language. Why? Through my experience working with new developers from more than 50 countries, I can confidently say you have much higher chances of getting a software engineering job when you’ve mastered one language instead of knowing a bit of 10 different ones.

Not sure what language to focus on? You’re in luck — this article is for you.

Not sure where to start? Learn a general-purpose language.

I recommend that any new developer who doesn’t know what to start learning pick a general-purpose programming language, because they’re used widely and not limited to one domain.

Python

Python’s simple, straightforward syntax makes it a great general-purpose language to master. The language features a dynamic type system, automatic memory management, and supports multiple programming paradigms like object-oriented, functional, and imperative. Many application domains use its comprehensive standard library.

Web and desktop applications, servers, machine learning, and artificial intelligence applications all use Python. It continually ranks in the top programming languages each year, with last year getting the “Programming language of the year” award in the TIOBE Programming Community Index for the highest rise in ratings. I imagine it will rise even more in 2019.

Number of available jobs as a Python developer on Indeed.com: 66,000+

JavaScript

According to the annual developer insight survey on Stack Overflow, over 70% of all developers use JavaScript. It’s versatile, can be applied in almost any software field, is one of the primary front-end languages of the World Wide Web. JavaScript also enables interactive web pages and is essential to most web applications.

JavaScript is a multi-paradigm language and supports multiple programming styles from object-oriented to functional. It also has a vast, rapidly expanding number of libraries, including some back-end servers. It’s so popular that it even has frameworks in fields where it’s not the best option, such as in game development and virtual reality.

Number of available jobs as a JavaScript developer on Indeed.com: 40,000+

Ruby

Like the other languages, Ruby supports multiple programming paradigms like object-oriented, functional, and imperative. It also features a dynamic type system and automatic memory management. Ruby is mostly used in web applications with the Ruby on Rails framework, but it’s also used in back-end servers and databases.

One of Ruby’s greatest assets is its friendliness towards beginners. It’s one of the most forgiving languages on the list — you’ll still be able to compile and run your program until a problem appears. It’s also easy to learn because its syntax is close to spoken language, and it can do what other languages do in much fewer lines of code.

Number of available jobs as a Ruby engineer on Indeed.com: 9,000+

Java

Java’s famous slogan is “write once, run anywhere” as it runs on any platform that supports it. Java is one of the most widely known languages among new developers, and it’s the second most used language on Stack Overflow.

Java is a multi-paradigm language that is class-based, object-oriented and designed to have the least implementation dependencies. Due to its structure, it has a wide array of uses across application domains. One of its most well-known uses is developing applications for Android, but it’s also popular for desktop, web, server, and network applications. While Java’s syntax can be daunting at first, mastering it can be well worth it for landing your first job as a developer.

Number of available jobs as a Java developer on Indeed.com: 68,000+

Have a specific field in mind?

If you already have a specific goal of working on machine learning, becoming a mobile developer, or joining a startup, consider mastering a language specific to that goal.

Machine learning

According to a report on GitHub, Python was the most used language for machine learning in 2018. Combine your Python knowledge with the TensorFlow library, and you’ll have put yourself in an excellent position to land an exciting job related to machine learning.

The R programming language would be the next best choice for machine learning. It’s the most effective for analyzing and manipulating data for statistical purposes. It also offers numerous packages that make implementing machine learning algorithms easy.

Mobile development

If you’re interested in developing mobile apps, you’ll have to decide if you want to develop for Android or Apple devices.

Java is your best bet for developing on Android. Mobile Java development is different than generic Java, though, due to the limited power of smartphones. For example, a regular Java program runs until you shut it down, while an Android app can be shut down at any time if it’s not running in the foreground.

On the iOS side, I recommend you learn Swift, Apple’s official language for iOS, macOS, and other code written for Apple products. Some people might suggest Objective-C because you can create graphical user interfaces and feature-rich frameworks, but I’d opt to learn Swift because it’s easier to learn, easier to read, and endorsed by Apple themselves.

JavaScript is another good option for mobile development. Combined with HTML and CSS, you can build apps that can be converted to native apps using Cordova. Another example is the .NET stack, which can also be used to build apps and convert them using Xamarin. Of course, these examples highlight the importance of learning a general-purpose language even more.

Startups

If you know you want to build or join a startup, nothing beats knowing Ruby and Ruby on Rails. Ruby is friendly towards beginners and allows developers to prototype quickly, which makes it an excellent choice for the fast-paced startups.

At Microverse, we’ve designed our curriculum to maximize the chances that our students get great jobs because we don’t earn anything until they’re employed. For that reason alone, our curriculum focuses on JavaScript, React, Ruby, and Ruby on Rails to help our students get jobs at startups.

Which languages to avoid?

There are many other languages to choose from. Some of the most popular ones now include Go, Scala, TypeScript, C++, and Rust.

However, if you’re starting to learn software development, you should avoid most of them. Many languages are complex, advanced, or too focused on a single application domain.

To summarize:

  1. Hyper-focus on mastering one language instead of learning a little bit about several languages.
  2. If you don’t know which language to start with, pick a general-purpose language.

Don’t stress out on which one you should choose because there are jobs for every language. What matters most is your motivation, determination, and ability to focus on learning and mastering your chosen language.

Best of luck!

 

Tip:

安全验证:所有请求不能轻易的进入。

登录验证。调用验证。用户有相关的内容或者权限才可以进行调用。不然就反空或者抛异常。

Share:

https://mp.weixin.qq.com/s/PhAHo_6_s9d6aP8-A77LnQ

【算法技巧】位运算装逼指南

帅地 Java团长 今天

 

作者:帅地     来源:公众号【苦逼的码农】


位算法的效率有多快我就不说,不信你可以去用 10 亿个数据模拟一下,今天给大家讲一讲位运算的一些经典例子。不过,最重要的不是看懂了这些例子就好,而是要在以后多去运用位运算这些技巧,当然,采用位运算,也是可以装逼的,不信,你往下看。我会从最简单的讲起,一道比一道难度递增,不过居然是讲技巧,那么也不会太难,相信你分分钟看懂。

1、判断奇偶数

判断一个数是基于还是偶数,相信很多人都做过,一般的做法的代码如下:

if( n % 2) == 01

    // n 是个奇数

}

如果把 n 以二进制的形式展示的话,其实我们只需要判断最后一个二进制位是 1 还是 0 就行了,如果是 1 的话,代表是奇数,如果是 0 则代表是偶数,所以采用位运算的方式的话,代码如下:

if(n & 1 == 1){
     

    // n 是个奇数。

}

有人可能会说,我们写成 n % 2 的形式,编译器也会自动帮我们优化成位运算啊,这个确实,有些编译器确实会自动帮我们优化。但是,我们自己能够采用位运算的形式写出来,当然更好了。别人看到你的代码,我靠,牛逼啊。无形中还能装下逼,是不是。当然,时间效率也快很多,不信你去测试测试。

2、交换两个数

交换两个数相信很多人天天写过,我也相信你每次都会使用一个额外来变量来辅助交换,例如,我们要交换 x 与 y 值,传统代码如下:

int tmp = x;

x = y;

y = tmp;

这样写有问题吗?没问题,通俗易懂,万一哪天有人要为难你,不允许你使用额外的辅助变量来完成交换呢?你还别说,有人面试确实被问过,这个时候,位运算大法就来了。代码如下:

x = x ^ y   // 1

y = x ^ y   // 2

x = x ^ y   // 3

我靠,牛逼!三个都是 x ^ y,就莫名交换成功了。在此我解释下吧,我们知道,两个相同的数异或之后结果会等于 0,即 n ^ n = 0。并且任何数与 0 异或等于它本身,即 n ^ 0 = n。所以,解释如下:

把(1)中的 x 带入 (2)中的 x,有

y = x^y = (x^y)^y = x^(y^y) = x^0 = x。 x 的值成功赋给了 y。

对于(3),推导如下:

x = x^y = (x^y)^x = (x^x)^y = 0^y = y

这里解释一下,异或运算支持运算的交换律和结合律哦。

以后你要是别人看不懂你的代码,逼格装高点,就可以在代码里面采用这样的公式来交换两个变量的值了,被打了不要找我。

讲这个呢,是想告诉你位运算的强大,让你以后能够更多着去利用位运算去解决一些问题,一时之间学不会也没事,看多了就学会了,不信?继续往下看,下面的这几道题,也是非常常见的,可能你之前也都做过。

3、找出没有重复的数

给你一组整型数据,这些数据中,其中有一个数只出现了一次,其他的数都出现了两次,让你来找出一个数 。

这道题可能很多人会用一个哈希表来存储,每次存储的时候,记录 某个数出现的次数,最后再遍历哈希表,看看哪个数只出现了一次。这种方法的时间复杂度为 O(n),空间复杂度也为 O(n)了。

然而我想告诉你的是,采用位运算来做,绝对高逼格!

我们刚才说过,两个相同的数异或的结果是 0,一个数和 0 异或的结果是它本身,所以我们把这一组整型全部异或一下,例如这组数据是:1,  2,  3,  4,  5,  1,  2,  3,  4。其中 5 只出现了一次,其他都出现了两次,把他们全部异或一下,结果如下:

由于异或支持交换律和结合律,所以:

1^2^3^4^5^1^2^3^4 = (1^1)^(2^2)^(3^3)^(4^4)^5= 0^0^0^0^5 = 5。

也就是说,那些出现了两次的数异或之后会变成0,那个出现一次的数,和 0 异或之后就等于它本身。就问这个解法牛不牛逼?所以代码如下:

int find(int[] arr){
     

    int tmp = arr[0];

    for(int i = 1;i < arr.length; i++){
     

        tmp = tmp ^ arr[i];

    }

    return tmp;

}

时间复杂度为 O(n),空间复杂度为 O(1),而且看起来很牛逼。

4、m的n次方

如果让你求解 m 的 n 次方,并且不能使用系统自带的 pow 函数,你会怎么做呢?这还不简单,连续让 n 个 m 相乘就行了,代码如下:

int pow(int n){
     

    int tmp = 1;

    for(int i = 1; i <= n; i++) {
     

        tmp = tmp * m;

    }

    return tmp;

}

不过你要是这样做的话,我只能呵呵,时间复杂度为 O(n) 了,怕是小学生都会!如果让你用位运算来做,你会怎么做呢?

我举个例子吧,例如 n = 13,则 n 的二进制表示为 1101, 那么 m 的 13 次方可以拆解为:

m^1101 = m^0001 * m^0100 * m^1000

我们可以通过 & 1和 >>1 来逐位读取 1101,为1时将该位代表的乘数累乘到最终结果。直接看代码吧,反而容易理解:

int pow(int n){
     

    int sum = 1;

    int tmp = m;

    while(n != 0){
     

        if(n & 1 == 1){
     

            sum *= tmp;

        }

        tmp *= tmp;

        n = n >> 1;

    }



    return sum;

}

时间复杂度近为 O(logn),而且看起来很牛逼。

这里说一下,位运算很多情况下都是很二进制扯上关系的,所以我们要判断是否是否位运算,很多情况下都会把他们拆分成二进制,然后观察特性,或者就是利用与,或,异或的特性来观察,总之,我觉得多看一些例子,加上自己多动手,就比较容易上手了。所以呢,继续往下看,注意,先别看答案,先看看自己会不会做。

5、找出不大于N的最大的2的幂指数

传统的做法就是让 1 不断着乘以 2,代码如下:

int findN(int N){
     

    int sum = 1;

   while(true){
     

        if(sum * 2 > N){
     

            return sum;

        }

        sum = sum * 2;

   }

}

这样做的话,时间复杂度是 O(logn),那如果改成位运算,该怎么做呢?我刚才说了,如果要弄成位运算的方式,很多时候我们把某个数拆成二进制,然后看看有哪些发现。这里我举个例子吧。

例如 N = 19,那么转换成二进制就是 00010011(这里为了方便,我采用8位的二进制来表示)。那么我们要找的数就是,把二进制中最左边的 1 保留,后面的 1 全部变为 0。即我们的目标数是 00010000。那么如何获得这个数呢?相应解法如下:

1、找到最左边的 1,然后把它右边的所有 0 变成 1

 

2、把得到的数值加 1,可以得到 00100000即 00011111 + 1 = 00100000。

3、把 得到的 00100000 向右移动一位,即可得到 00010000,即 00100000 >> 1 = 00010000。

那么问题来了,第一步中把最左边 1 中后面的 0 转化为 1 该怎么弄呢?我先给出代码再解释吧。下面这段代码就可以把最左边 1 中后面的 0 全部转化为 1,

n |= n >> 1;

n |= n >> 2;

n |= n >> 4;

就是通过把 n 右移并且做运算即可得到。我解释下吧,我们假设最左边的 1 处于二进制位中的第 k 位(从左往右数),那么把 n 右移一位之后,那么得到的结果中第 k+1 位也必定为 1,然后把 n 与右移后的结果做或运算,那么得到的结果中第 k 和 第 k + 1 位必定是 1;同样的道理,再次把 n 右移两位,那么得到的结果中第 k+2和第 k+3 位必定是 1,然后再次做或运算,那么就能得到第 k, k+1, k+2, k+3 都是 1,如此往复下去….

最终的代码如下:

int findN(int n){
     

    n |= n >> 1;

    n |= n >> 2;

    n |= n >> 4;

    n |= n >> 8 // 整型一般是 32 位,上面我是假设 8 位。

    return (n + 1) >> 1;

}

这种做法的时间复杂度近似 O(1),重点是,高逼格。

总结

上面讲了 5 道题,本来想写十道的,发现五道就已经写了好久了,,,,十道的话,怕你们也没耐心写完,而且一道比一道难的那种,,,,。

不过呢,我给出的这些例子中,并不是让你们学会了这些题就 Ok,而且让你们有一个意识:很多时候,位运算是个不错的选择,至少时间效率会快很多,而且高逼格,装逼必备。所以呢,以后可以多尝试去使用位运算哦,以后我会再给大家找些题来讲讲,遇到高逼格的,感觉很不错的,就会拿来供大家学习了。

(完)

 

你可能感兴趣的:(ARTS,位运算)